Functions and Parameter Passing
Functions give a named interface to a reusable computation. Parameters bring data in, return values bring a result out, and references can intentionally modify the caller’s object. Good function boundaries make it easier to reason about each part separately and test small units. We compare a local modification with a reference modification, then use a const-reference function to find a string’s length without copying or changing it.
Prerequisites: Loops, variables and basic strings as input tokens; detailed string operations follow shortly.
Build the idea
1. Describe input and output of a function
int square(int x) receives a value and returns x*x. The parameter x is local to that call; changing it does not change a caller’s variable. A function’s return type and actual returned expression should agree. void means the function does not return a value, though it may perform output or change referenced objects. A return exits the current function, not the entire program unless it is main.
2. Follow pass-by-value
changeCopy(int x) receives a new integer initialized from the argument. Incrementing x changes only that copy. If the caller has value=5, changeCopy(value) leaves value at 5. Value passing is natural for small integers because copying is cheap and isolates side effects. A similarly passed vector or long string would copy all its elements, which may be unnecessary.
3. Use references for intentional mutation
A parameter int& x aliases the caller’s integer. increment(value) therefore changes value itself. The ampersand belongs to the type here; it is not the bitwise AND operation. Make mutating behavior clear in the function name and explanation. Returning a value is often simpler when a function computes one independent result rather than updates several caller objects.
4. Use const references for read-only large objects
const std::string& text gives read-only access without copying the whole string. text.size() obtains its stored length in constant time. const prevents modification through this reference; it does not make every other alias in the program immutable. Local names exist only in their enclosing scope, so another function cannot use main’s local variables unless they are passed or otherwise made available.
5. Trace call order
For input 5 hello, changeCopy temporarily works with 6 but the caller still prints 5. increment then changes the caller to 6. square(6) returns 36, and lengthOfWord returns 5. The output records the original-after-copy value, modified value, square and word length. The functions are defined before main so the compiler knows their declarations when calls are encountered.
C++17 implementation
This is a complete program. Compile with C++17 and enter the input described below.
#include<iostream>
#include<string>
int square(int x){
return x*x;
}
void changeCopy(int x){
++x;
} // Changes only a local copy.
void increment(int&x){
++x;
} // Changes the caller's variable.
std::size_t lengthOfWord(const std::string&text){
return text.size();
}
int main(){
int value;
std::string word;
std::cin>>value>>word;
changeCopy(value);
std::cout<<value<<' ';
increment(value);
std::cout<<value<<' '<<square(value)<<' '<<lengthOfWord(word)<<'\n';
}
Complexity analysis
The function calls perform O(1) work each; passing a const string reference does not copy its characters, and string::size is O(1). Reading a word of length L takes O(L) time and O(L) storage. The integer square is safe under the stated small value bound.
Example input and output
Read integer value in −100..100 and one nonempty word. Print the caller value after a by-value call, after an increment-by-reference call, its square, and the word length.
Input
5 hello
Output
5 6 36 5
The copy call cannot change value. The reference call changes it to 6; 6²=36 and hello has length 5.
Practical applications
Use functions to express one responsibility: read, transform, check feasibility, or compute an answer. Prefer value passing for small scalar inputs, const references for read-only containers, and references for explicit updates. Later binary-search checks and recursive algorithms rely on these interfaces.
Check your understanding
Why pass a large read-only string by const reference?
Put it into practice
Write a function that returns the larger of two integers without changing either.
Show a hint
Use value parameters and a return statement; compare with std::max in the STL lesson.