Functions · Getting started
Functions and copies
Follow a function call, its separate input number and the result it sends back.
A function is a named set of instructions.
A function groups instructions under a name so you can ask it to do the same job with different inputs. Writing its definition describes the job; a call asks it to run. Start with the definition and call example. If int, = or stored values are unfamiliar, use the optional C++ first steps preparation first. This visit focuses only on passing whole-number copies; references come later.
Describing a job does not run it.
int addTwo(int number) defines a function named addTwo. The first int says it sends a whole number back. The part in parentheses describes its input; we explain that next. The braces { } enclose the job's instructions. return number + 2; finishes a call and sends that calculated number back. The definition goes outside main. The last two instructions go inside main: create score, then call addTwo to calculate a result. Writing the definition alone does not change score.
int addTwo(int number) {
return number + 2;
}
// These instructions are inside main:
int score = 4;
int result = addTwo(score);An input has a name inside the function.
In the definition addTwo(int number), number is the function's input name: a parameter. In the call addTwo(score), score supplies the input value: an argument. These names need not match. The code making the call is the caller. If score holds 4, this plain int parameter receives its own copy of 4. number belongs to this call, while score still belongs to the caller. Next follow the steps that return a result.
A call takes a temporary detour.
Read the two instructions inside main first. score starts at 4. To create result, evaluate addTwo(score): copy 4 into the function's parameter number, calculate number + 2 as 6, then return 6 to the waiting instruction. That instruction stores 6 in result. score stays 4. The parameter belongs to this call; it is not a second name for score. After the call, continue with the caller's next instruction.
int addTwo(int number) {
return number + 2;
}
// Inside main:
int score = 4;
int result = addTwo(score);The input copy and the caller are separate.
During addTwo(score), the caller's score holds 4 and the local parameter number also holds 4 in a separate place. Local means it belongs to this function call. The addition produces the returned 6; it does not assign anything to score. Once the call finishes, its local parameter is gone and result holds the returned value. This is a picture of values, not physical addresses.
- Caller: score
- value: 4
- Call: number
- separate copy: 4
- Returned result
- 4 + 2 = 6
- Caller: score leads to Call: number (copy at call)
- Call: number leads to Returned result (calculate + 2)
Changing a copy and returning it are different jobs.
In this different example, coins in the caller remains 9 while spendOne works with its separate number, 9 then 8. return sends 8 back; it does not search for and update coins. remaining receives 8 because the caller explicitly stores the result there. Next compare that with deliberately assigning the result back to the original name.
int spendOne(int number) {
number = number - 1;
return number;
}
// Inside main:
int coins = 9;
int remaining = spendOne(coins);The caller chooses where to store the result.
Here number receives a copy of score, 4. addTwo calculates and returns 6. The caller's score = addTwo(score); then stores that 6 back in score. This changes score because of assignment in the caller, not because the parameter is connected to score. If you instead write addTwo(score); alone, the function still runs, but its returned number is not stored anywhere.
int addTwo(int number) {
return number + 2;
}
// Inside main:
int score = 4;
score = addTwo(score);Stop with one clear distinction.
A value parameter is a separate input copy. A returned number changes a caller variable only when the caller stores it there. You can stop here and revisit the examples another day. When comfortable, References shows the different case: giving a function another name for the original object. Getting one check right is useful practice, not proof that all function behavior is understood.
Further reading
Trusted resources for the rules and APIs discussed in this guide.