Understanding Subroutine Parameters
Formal parameters are the variables declared in a subroutine's parameter list, and actual parameters are the values or expressions supplied in the call statement.
Commit to a Prediction First
Many beginners can use a subroutine that already exists without much trouble. Passing information into it through a parameter feels natural. The difficulty appears when you have to write the subroutine yourself, because then you must decide what the parameter variables are supposed to hold and when they get their values. This article focuses on exactly that moment.
What do you think happens?
A subroutine's parameter list declares three names, and another part of the program calls it with three expressions. Where do the three parameter variables get their values, and at which point in time?
Reveal answer
The computer assigns the actual parameter values to the formal parameters before it executes the statements inside the subroutine.
The body never needs to set or request the parameter values. The call statement supplies them, and the assignment happens before the body starts running.
Two Kinds of Parameters
Formal parameters are the variables declared in a subroutine's parameter list. Actual parameters are the values or expressions supplied in the call statement. The formal parameter is the name the subroutine uses internally, and the actual parameter is the value the caller provides.
The two terms are easy to mix up because they appear side by side in the same line of code. A useful way to keep them apart is to ask where each one is written. A formal parameter is written in the definition of the subroutine. An actual parameter is written at the place where the subroutine is used.
| Question | Formal parameter | Actual parameter |
|---|---|---|
| Where is it written? | In the subroutine's parameter list (the header) | In the call statement, where the subroutine is used |
| What is it? | A declared variable name with a type | A value or expression supplied by the caller |
| Who chooses it? | The author of the subroutine | The code that makes the call |
| When does it get a value? | When the call is made, before the body runs | Its value is computed and then passed in at the call |
| Example role | count, root, ok in the header | 7, Math.sqrt(16), and 3 > 2 in the call |
Formal and actual parameters compared
Reading the Header and the Call
The example below uses Java-style syntax, in the same spirit as the source. Each entry in the parameter list has a type and a name. The names are the formal parameters. They are declared once, in the header, and the body of the subroutine can refer to them by name.
- count, root, and ok are the formal parameters, declared in the header with their types
- 7,
Math.sqrt(16), and 3 > 2 are the actual parameters, written in the call statement - The header contains no values, only the names and types of three slots
What Happens During a Call
Executing one call statement has essentially the same effect as a block of statements that does its work in a fixed order. First, the computer allocates storage for the formal parameters. Second, it assigns the first actual value to the first formal parameter. It computes any expression in the call, such as the square root, and assigns the result to the second formal parameter. It evaluates the comparison and assigns its true or false result to the third. Only after that does the body of the subroutine run.
- 1The call statement is reached. Its actual parameter expressions are evaluated first.
- 2The results of those expressions are assigned to the formal parameters, matched by position.
- 3Only after every formal parameter holds its value does the subroutine body begin executing.
- 4The body uses the formal parameter names. It never has to set or ask for them.
Matching Values to Slots by Position
Matching between actual and formal parameters follows position. The first actual parameter feeds the first formal parameter, the second feeds the second, and so on. The names on each side do not need to match. Only the order does.
Tracing the report call
Given the report method above, what does the call report(7, Math.sqrt(16), 3 > 2) print?
- 1Evaluate the actual parameters
7 is already a value.
Math.sqrt(16)is computed as 4.0. The comparison 3 > 2 is evaluated to true. - 2Assign by position
The first value goes to count, the second to root, and the third to ok.
- 3Run the body
The body prints count, which holds 7, then root, which holds 4.0, then ok, which holds true.
The output is 7, then 4.0, then true, each on its own line.
The Body-Assignment Misconception
A widespread misconception is that the parameters in a subroutine's header are empty slots that the subroutine fills in once it begins running. Under this belief, the first lines of the subroutine would assign values to the parameter variables, or the subroutine would ask the user to type them in. Both approaches seem reasonable if you imagine the subroutine as a self-contained program that wakes up and prepares its own inputs. They are wrong, because the values already arrived at the call.
Common mistake Assigning parameter values at the top of the body
What it looks likevoid report(int count) { count = 7; System.out.println(count); }Why it failsThe call has already supplied a value to count before the body starts. The assignment overwrites the caller's value with a value the body picked itself, which ignores the actual parameter entirely.
Do this insteadUse the formal parameter directly and let the call supply its value: void report(int count) { System.out.println(count); }Common mistake Asking the user to type in a parameter value inside the subroutine
Why it failsThe subroutine is not meant to request its inputs. Its inputs are the actual parameters from the call, so prompting inside the body reflects the same misunderstanding of when values arrive.
Do this insteadHave the caller read the input, then pass the value in the call statement.
Common mistake Thinking the names in the call must match the names in the header
Why it failsMatching follows position, not name. The first actual parameter feeds the first formal parameter whatever either one is called.
Do this insteadCheck the order of the actual parameters against the order of the declared formal parameters.
Practice Predicting a Call
A subroutine is declared as void show(int a, int b, int c) and is called as show(2 + 3, 10, 4 * 2). Without running anything, state the value of a, b, and c at the moment the body begins, and say at which point in the call sequence those values were assigned.
Hints
- Evaluate each actual parameter expression first: 2 + 3 gives 5, and 4 * 2 gives 8.
- Match by position: the first actual goes to a, the second to b, the third to c.
- The assignments happen before the first statement of the body runs.
Key Takeaways
- Formal parameters are the variables declared in a subroutine's parameter list. Actual parameters are the values or expressions supplied in the call statement.
- The computer assigns actual parameter values to formal parameters before it executes the statements inside the subroutine. The body never needs to set or request them.
- Expressions in the call are evaluated before their results are assigned, and matching follows position, not name.
- Assigning values to formal parameters at the top of the body, or asking the user for them, reflects a fundamental misunderstanding of how subroutine calls work.
- The assignment-block model captures the overall effect of a call, but it is a model rather than a complete description of the machinery.