Functions are the basic building blocks of any C++ program. They allow you to group instructions into reusable units. In C++, every function must specify what type of data it returns and what types of parameters it accepts.
Unlike languages like Java where object references and primitives are passed by value (references copy the address, not the object itself), C++ gives you precise control over how arguments are passed to functions in memory.
Declaring vs Defining Functions
In C++, a function must be known to the compiler before you call it. This leads to two terms:
* Declaration (Prototype): Tells the compiler the function's name, return type, and parameters. It doesn't contain the body. Example: int add(int a, int b);.
* Definition: Contains the actual body of the function. Example: int add(int a, int b) { return a + b; }.
If you try to call a function defined later in the file without declaring it first, the compiler will throw an error. It does not look ahead to see if you meant well.
Parameter Passing Modes
When you pass variables to a function, you must choose one of three memory passing modes:
1. Pass by Value (Copying)
By default, C++ passes arguments by value. This means the compiler makes a complete copy of the variable and stores it on the function's new stack frame. Any changes made inside the function do not affect the original variable.
Pass by value is efficient for small, primitive types (like int, char, double), but copying large objects (like standard vectors or strings) creates massive memory overhead.
2. Pass by Reference (Aliasing)
If you want to modify the original variable, or avoid copying a large object, you pass it by reference by appending an ampersand & to the parameter type.
A reference acts as an alias (another name) for the original variable. No copy is made; the function operates directly on the caller's memory address.
If you want to avoid copy overhead but guarantee that the function does not modify the original variable, you should use a const reference (e.g. const std::string& name). This is the industry standard for passing large objects.
3. Pass by Pointer (Address Sharing)
Pass by pointer is the traditional C style method. You pass the physical memory address of the variable by using a pointer type T. Inside the function, you must dereference the pointer using to read or write the value.
Unlike references, pointers can be set to nullptr (pointing to nothing), so you should always check if a pointer is null before dereferencing it to avoid segment faults. Dereferencing a null pointer is the programming equivalent of stepping on a rake in the dark.
Summary Guideline
* Use pass by value for small primitive types (int, float, bool).
* Use pass by const reference for large objects (string, vector, struct) that you only want to read.
* Use pass by reference when you explicitly need to modify the original object.
* Use pass by pointer only when the argument is optional (can be null) or when interfacing with legacy C APIs.