Parameters and return values change functions from a fixed piece of code that does one thing into something that receives some data, does something to it, and returns an answer.
A parameter is a variable declared inside the function header, within the parentheses. At the call site of a function, the parameter is created and initialized with some value supplied by the caller.
The value the caller gives is called the argument. The parameter is the "slot" created by the function, while the argument is the actual "thing" put into it at the call site.
By default, the argument passed into the function is copied in. This is called pass by value.
The parameter becomes its own local variable, and whatever happens to it remains inside the function, while not affecting the original argument that was passed in.
#include <iostream>
void try_to_change(int value)
{
value = value + 10;
std::cout << "Inside the function the copy is " << value << '\n';
}
int main()
{
int original{20};
try_to_change(original);
std::cout << "Back in main the original is still " << original << '\n';
}
If an int 20 is passed in to a function, a new int parameter called "the number I was passed in" is created containing 20. The function can happily add 10 to "the number I was passed in," and only "the number I was passed in" will contain 30, and the original argument 20 will contain just that, 20.
When the function finishes, "the number I was passed in" dies (along with its value 30), but 20 remains safe. The advantage of pass by value is that it protects the caller data, making it generally easier to reason with.
A function may take any number of arguments, each being declared with a type. Arguments are placed separated by commas in the function header; arguments at the call site are separated by commas in the call site.
Arguments must match the parameters in number and order, and the type of the argument must be the same or be convertible to the required parameter type, otherwise you'll get a compilation error.
Values are sent back by using the return keyword.
A function's return type is declared in the function header before its name. A statement in the function body with the return keyword evaluates an expression and immediately sends the result of that expression back to the caller.
Nothing after a return statement (that has been executed) is run.
#include <iostream>
int add(int a, int b)
{
// Return the computed value to the caller
return a + b;
}
int main()
{
int sum{add(7, 5)};
std::cout << "The returned sum is " << sum << '\n';
}
If a function called with 7 and 5 adds 7 and 5, it may then return 12; this value may be assigned to another variable, placed in another expression, or used as a function argument.
If a function is declared with the return type void, it cannot return any value. If a function declared to return an int is exited by its final brace without a return statement, the behavior is technically undefined; a compiler might show a warning, but not necessarily reject the program.
Parameters and return values may both exist in a function:
Data is put into the function using parameters, and if a value is needed at the call site, it can be sent out from the function using a return value. A return value may also be directly passed into the caller, rather than assigned to a variable first.
For example:
A function can take two integers, add them, and return an integer; that integer may be passed into another function, which can then take the previous answer and multiply it by two and return the answer.
#include <iostream>
int add(int a, int b)
{
return a + b;
}
int multiply_by_two(int value)
{
return value * 2;
}
int main()
{
// Store the value produced by this function call
int result{multiply_by_two(add(7, 5))};
std::cout << "Result is " << result << '\n';
}
Each function receives a separate pair of parameters, executes some local work, and returns a separate answer. Starting the two functions: first 7 is put in parameter for the ADD function; ADD does its work and returns 12.
The number 12 is put into parameter for MULTIPLY, MULTIPLY doubles it and returns 24. This is returned by the first call and placed in original caller's memory.
Again, each function uses its own separate local variable parameters; they are completely disconnected from each other.
Only one value may be returned from a function per call. In the case that multiple results are required after a function call, some of them may be calculated within the function and included in the one return value.
int calculate_total(int first, int second, int third)
{
int total{first + second + third};
return total;
}
A parameter is basically a local variable, so it is alive only during the duration of the function call. A subsequent call creates a whole new local variable and a whole new parameter with their own lifetimes.
int square(int value)
{
return value * value;
}
// Initialize first with the value returned by square
int first{square(3)};
int second{square(5)};
Returning a parameter value is safe, because it is sent back to the caller before the parameter dies.
Parameters give a function an input; the return keyword gives it an output. When passing by value, parameters are copied inside the function and protected from being accidentally changed by local function variables in unintended ways.
Exercise: Parameters and Return ValuesStarter code, hints and solutionOpenClose
Practice: Parameters and Return Values
Work through the mission, reveal hints only when needed, and compare your result with the model solution.
Your challenge
Add a call that passes add(2, 3) into multiply_by_two and prints the final result. Trace which function finishes first.
Mission checklist
- Run the starter as a baseline, then predict the change requested in Your challenge.
- Make that change in your editor; use the lesson-specific hints if you need help.
- Compile and run your answer, then compare with the worked solution and explain the result.
Starter program
This is the working baseline, not the completed answer. Compile as C++20, then make the change described above.
#include <iostream>
int add(int a, int b)
{
return a + b;
}
int multiply_by_two(int value)
{
return value * 2;
}
int main()
{
// Store the value produced by this function call
int result{multiply_by_two(add(7, 5))};
std::cout << "Result is " << result << '\n';
}Hints
The result of add(7, 5) becomes the argument to multiply_by_two. Finish the inner addition before tracing the outer function body.
Add a separate nested call using add(2, 3). Its return value is the argument to multiply_by_two; print that outer return value in main.
Worked solution
The added nested call first computes add(2, 3), returning 5, then passes that value to multiply_by_two, returning 10. main receives the final result only.
#include <iostream>
int add(int a, int b)
{
return a + b;
}
int multiply_by_two(int value)
{
return value * 2;
}
int main()
{
// Store the value produced by this function call
int result{multiply_by_two(add(7, 5))};
std::cout << "Result is " << result << '\n';
std::cout << "New result: " << multiply_by_two(add(2, 3)) << '\n';
}
Example output
Result is 24
New result: 10
0 comments
No comments yet. Be the first.