Pass by Value
Every argument is a copy: what that means, what it forbids, and the swap function that fails because of it.
Every Argument Is a Copy
One rule governs every function call in C, and half the surprises of this chapter dissolve once it is exact: arguments are passed by value. The parameter is a fresh variable, initialized with a copy of the argument; the function computes with the copy, and the caller's variable never hears about any of it. This lesson makes the rule concrete, shows the famous function it breaks, and names the two-part escape route the coming chapters build.
Watching the Copy
Inside, n becomes 100; outside, amount remains 50. The assignment was real, but it targeted the copy. Drawing the memory picture makes it obvious: main has a patch named amount holding 50; the call creates a separate patch named n, initialized to 50; the function writes 100 into its own patch, which is discarded when the function returns. Two patches, one moment of copying, no further connection.
The rule cuts both ways, and the productive direction matters as much as the surprising one: because the parameter is the function's private copy, a function can scribble on its parameters freely, decrementing counters, peeling digits, without documenting any effect on the caller. Parameters are initialized local variables, nothing more.
The Function It Breaks
The canonical casualty, on every exam since the beginning:
The output is x = 1, y = 2: nothing swapped. Inside swap, the copies exchange values flawlessly, and both copies then evaporate. No rearrangement of this function fixes it; with pass-by-value alone, no function can modify its caller's variables. When the exam presents this program and asks for the output, the unswapped values are the answer, and "the parameters are copies" is the one-line justification.
The Escape Route
The workaround you already own: return. A function that computes a new value hands it back, and the caller stores it:
The assignment happens in main, on main's variable, with the function's result. This return-and-assign shape covers every single-result function, and it is the course's default: compute in the function, store in the caller.
But return carries one value, and swap needs to change two. The real fix is to hand the function not the values but the addresses of the caller's variables, the &x you have written in every scanf since chapter 1. scanf could always modify your variables precisely because you passed addresses; making that mechanism yours is the pointers chapter, where swap returns and finally works. For now, the honest summary: pass-by-value is the rule, return is the front door, and addresses are the back door with its own chapter.
One More Consequence: Expressions as Arguments
Because only the value crosses the boundary, any expression can be an argument: cube(x + 1), doubled(doubled(5)), cube(scanf's guarded result). The expression is evaluated, the result copied in. This is also why the argument-evaluation order caution from chapter 3 applies to calls: f(i++, i) modifies and reads i with no sequencing between the arguments, undefined behaviour wearing a function call's clothes. Arguments stay side-effect-free in course code.
Key Takeaways
- Parameters are fresh variables initialized with copies of the argument values; functions never see caller variables.
- A function may freely modify its parameters; the caller is unaffected, in both the surprising and the useful direction.
- The value-passing swap can never work, and its unswapped output plus the one-line reason is a standing exam answer.
- The standard escape is return-and-assign in the caller; multiple results need addresses, scanf's trick, formalized in the pointers chapter.
- Any expression can be an argument, but side effects in argument lists risk the unsequenced-modification UB from chapter 3.
How did you find this lesson?
Your rating helps us improve the content.
Create an account to track your progress and access interactive exercises. Already have one? Sign in.
Pass by Value - Quiz
Test your understanding of the lesson.
Practice Exercises
Return and Assign
Write int maxOfThree(int a, int b, int c) that returns the largest of its three parameters, and a main that reads three guarded ints, stores the function's result, and reports it. One value out, stored by the caller: the return-and-assign shape.
Lesson Discussion
Share your thoughts and questions
No comments yet. Be the first to share your thoughts!