11.3.3 Parameters, Arguments and Subroutine Interfaces
A reusable subroutine should be able to process different data each time it is called. Parameters provide named entry points through which the caller supplies that data.
The subroutine header describes its interface. The call must supply suitable arguments in the correct order. For procedures, the interface may also specify whether a parameter receives a separate value or refers to a variable belonging to the caller.
By the end of this section, you should be able to:
- Explain why parameters make subroutines reusable.
- Distinguish between an argument and a parameter.
- Identify a procedure or function header.
- Explain the purpose of a subroutine interface.
- Write subroutines with no parameters, one parameter or several parameters.
- Match arguments to parameters by position.
- Check that argument and parameter data types are compatible.
- Use literals, variables and expressions as suitable arguments.
- Explain parameter passing by value.
- Explain parameter passing by reference.
- Predict whether a caller variable changes after a procedure call.
- Write procedure headers containing
BYVALandBYREF. - Recognise that function parameters should be passed by value.
- Trace caller data, parameter data and changes made during a call.
Why Do Subroutines Need Parameters?
Without parameters, a subroutine either performs exactly the same operation every time or depends on data stored elsewhere in the program. Parameters allow the caller to provide different values for each call.
Fixed procedure
PROCEDURE ShowNorthReading()
OUTPUT "North sensor: 72.5"
ENDPROCEDURE
This procedure is tied to one location and one value.
Reusable procedure
PROCEDURE DisplayReading(
SensorName : STRING,
Reading : REAL
)
OUTPUT SensorName, " sensor: ", Reading
ENDPROCEDURE
CALL DisplayReading("North", 72.5)
CALL DisplayReading("East", 64.8)
CALL DisplayReading("Roof", 81.3)
One procedure definition can now display many different readings.
Arguments, Parameters, Headers and Interfaces
PROCEDURE DisplayReading(
SensorName : STRING,
Reading : REAL
)
OUTPUT SensorName, " sensor: ", Reading
ENDPROCEDURE
CALL DisplayReading("Roof", 81.3)
| Term | Location | Example | Meaning |
|---|---|---|---|
| Argument | Subroutine call | "Roof", 81.3 |
An actual value or expression supplied by the caller |
| Parameter | Subroutine header | SensorName, Reading |
A named variable through which the subroutine receives data |
| Header | Start of the definition | PROCEDURE DisplayReading(...) |
Identifies the subroutine and its parameter requirements |
| Interface | Boundary between caller and subroutine | Name, parameters, types and passing modes | Describes how the subroutine must be used |
| Caller | Code containing the call | Main program | Supplies arguments and continues after the call |
Subroutine Headers and Calls
Procedure header
PROCEDURE DisplayReading(
SensorName : STRING,
Reading : REAL
)
Procedure call
CALL DisplayReading("Roof", 81.3)
Function header
FUNCTION CalculateCost(
UnitPrice : REAL,
Quantity : INTEGER
) RETURNS REAL
Function call
TotalCost ← CalculateCost(6.25, 4)
| Subroutine | How it is invoked | Result |
|---|---|---|
| Procedure | CALL ProcedureName(...) |
Performs an action and returns control |
| Function | Call appears inside an expression | Returns one value that replaces the call |
CALL before a function call. A function call belongs
in an expression, assignment, condition or output statement.
The Subroutine Interface
The interface is the agreed connection between a subroutine and the code that uses it. A caller can use the subroutine correctly without knowing every internal statement.
Procedure interface
PROCEDURE RecordDelivery(
BYREF StockLevel : INTEGER,
BYVAL Delivered : INTEGER
)
| Interface element | Information communicated |
|---|---|
RecordDelivery |
The procedure identifier |
StockLevel |
The first parameter |
INTEGER |
The required data type |
BYREF |
The caller’s variable may be changed |
Delivered |
The second parameter |
BYVAL |
The procedure receives a separate value |
Function interface
FUNCTION CalculateCost(
UnitPrice : REAL,
Quantity : INTEGER
) RETURNS REAL
The function interface also includes the return type because callers need to know what kind of value replaces the function call.
Zero, One or Several Parameters
A subroutine may require no data, one item of data or several related values.
No parameters
PROCEDURE ShowDivider()
OUTPUT "--------------------"
ENDPROCEDURE
CALL ShowDivider()
One parameter
PROCEDURE ShowMessage(Message : STRING)
OUTPUT Message
ENDPROCEDURE
CALL ShowMessage("Calibration complete")
Several parameters
PROCEDURE DisplayReading(
SensorName : STRING,
Reading : REAL,
UnitSymbol : CHAR
)
OUTPUT SensorName, ": ", Reading, UnitSymbol
ENDPROCEDURE
CALL DisplayReading("Tank", 68.4, '%')
Arguments Are Matched by Position
PROCEDURE PrintLocationLabel(
Building : STRING,
RoomCode : STRING
)
Correct order
CALL PrintLocationLabel("Science Centre", "L204")
| Position | Argument | Parameter receiving it |
|---|---|---|
| 1 | "Science Centre" |
Building |
| 2 | "L204" |
RoomCode |
Reversed order
CALL PrintLocationLabel("L204", "Science Centre")
Both arguments are strings, so the call may still be type-compatible, but their meanings are reversed.
Argument and Parameter Data Types
PROCEDURE DisplayReading(
SensorName : STRING,
Reading : REAL,
IsEstimated : BOOLEAN
)
Compatible call
CALL DisplayReading("Reservoir", 45.7, FALSE)
Incorrectly formed call
CALL DisplayReading(45.7, "Reservoir", FALSE)
| Position | Expected type | Supplied type | Compatible? |
|---|---|---|---|
| 1 | STRING |
REAL |
No |
| 2 | REAL |
STRING |
No |
| 3 | BOOLEAN |
BOOLEAN |
Yes |
Literals, Variables and Expressions as Arguments
An argument may be a literal value, a variable or an expression, provided that it produces a compatible value.
PROCEDURE DisplayTotal(
Description : STRING,
Total : REAL
)
OUTPUT Description, ": ", Total
ENDPROCEDURE
| Argument form | Example call |
|---|---|
| Literal | CALL DisplayTotal("Fixed amount", 24.5) |
| Variable | CALL DisplayTotal("Current total", RunningTotal) |
| Arithmetic expression | CALL DisplayTotal("With tax", Price * 1.08) |
| Function call | CALL DisplayTotal("Area", CalculateArea(8, 5)) |
These forms work naturally for parameters passed by value because the expression is evaluated and its resulting value is supplied.
12 or an expression such as
Price * 1.08 does not identify a caller variable that can be
changed.
Passing a Parameter by Value
When an argument is passed by value, the parameter receives a separate value for the current call. Assigning to that parameter does not change the caller’s variable.
PROCEDURE AddOne(BYVAL Number : INTEGER)
Number ← Number + 1
OUTPUT "Inside procedure: ", Number
ENDPROCEDURE
DECLARE Attempts : INTEGER
Attempts ← 3
CALL AddOne(Attempts)
OUTPUT "After call: ", Attempts
| Stage | Caller variable Attempts |
Parameter Number |
|---|---|---|
| Before call | 3 | Does not yet exist for this call |
| Call begins | 3 | Receives 3 |
| Inside procedure | 3 | Changes to 4 |
| After procedure | 3 | Call has finished |
Output
Inside procedure: 4
After call: 3
When no passing mode is written, passing by value is assumed.
Passing a Parameter by Reference
A reference parameter is connected to the caller’s variable. Assigning through the parameter changes that caller variable.
PROCEDURE AddDelivery(
BYREF Quantity : INTEGER,
BYVAL Delivered : INTEGER
)
Quantity ← Quantity + Delivered
ENDPROCEDURE
DECLARE Stock : INTEGER
Stock ← 14
CALL AddDelivery(Stock, 6)
OUTPUT Stock
| Stage | Caller variable Stock |
Reference parameter Quantity |
|---|---|---|
| Before call | 14 | Not connected |
| Call begins | 14 | Refers to Stock |
| Assignment | Changes to 20 | Quantity ← 14 + 6 |
| After call | 20 | Connection ends |
Output
20
Comparing BYVAL and BYREF
| Feature | BYVAL |
BYREF |
|---|---|---|
| What does the parameter receive? | A separate value | A reference to a caller variable |
| Can assigning to the parameter change the caller variable? | No | Yes |
| Can a literal normally be supplied? | Yes | No, because there is no caller variable to update |
| Can an expression normally be supplied? | Yes | No, because the result is not a writable variable |
| Default when no mode is written | Yes | No |
| Suitable purpose | Provide input data | Allow a procedure to update caller data |
Using BYVAL and BYREF Together
One procedure can receive input values and also update selected caller variables.
PROCEDURE ApplyCorrection(
BYREF Reading : INTEGER,
BYVAL Offset : INTEGER,
BYREF AlertCount : INTEGER
)
Reading ← Reading + Offset
IF Reading > 75
THEN
AlertCount ← AlertCount + 1
ENDIF
ENDPROCEDURE
Temperature ← 84
Warnings ← 2
CALL ApplyCorrection(Temperature, -5, Warnings)
| Argument | Parameter | Mode | Result after the call |
|---|---|---|---|
Temperature |
Reading |
BYREF |
Caller variable changes from 84 to 79 |
-5 |
Offset |
BYVAL |
Literal supplies the correction value |
Warnings |
AlertCount |
BYREF |
Caller variable changes from 2 to 3 |
Grouping parameters with the same mode
PROCEDURE MovePoint(
BYREF X : INTEGER,
Y : INTEGER,
BYVAL ChangeX : INTEGER,
ChangeY : INTEGER
)
When adjacent parameters use the same method, the keyword does not need to be repeated for each parameter. Repeating it can still make a teaching example easier to read.
BYVAL or BYREF.
Parameters in Functions
Function parameters supply the data needed to calculate a returned value. They are passed by value.
FUNCTION CalculateCharge(
UnitRate : REAL,
HoursUsed : REAL
) RETURNS REAL
RETURN UnitRate * HoursUsed
ENDFUNCTION
Charge ← CalculateCharge(3.75, 6.0)
| Interface part | Example |
|---|---|
| Function name | CalculateCharge |
| First parameter | UnitRate : REAL |
| Second parameter | HoursUsed : REAL |
| Return type | REAL |
| Arguments | 3.75, 6.0 |
| Returned value | 22.5 |
Designing a Clear Subroutine Interface
A good interface communicates what the subroutine needs and which caller variables it may change.
| Design question | Useful decision |
|---|---|
| What task does the subroutine perform? | Choose a meaningful procedure or function name |
| What data must the caller provide? | Create parameters with suitable identifiers and data types |
| Which values are input-only? | Pass them by value |
| Which caller variables must be updated? | Use reference parameters in a procedure |
| Does the task produce one value? | Consider a function and declare its return type |
| Is every parameter necessary? | Remove values not used by the subroutine |
| Is the order clear? | Group related values and use descriptive names |
Unclear interface
PROCEDURE Process(A : INTEGER,
B : INTEGER,
C : INTEGER)
Clearer interface
PROCEDURE UpdateInventory(
BYREF StockLevel : INTEGER,
BYVAL Delivered : INTEGER,
BYVAL Damaged : INTEGER
)
BYREF hides which caller variables the procedure genuinely
intends to change.
A Reliable Method for Tracing Parameter Passing
- Locate the subroutine header and record its parameters in order.
- Record each parameter’s data type and passing mode.
- Locate the call and number its arguments from left to right.
- Match each argument to the parameter in the same position.
- For
BYVAL, create a separate parameter value. - For
BYREF, record which caller variable the parameter refers to. - Execute the subroutine body in order.
- Record assignments to value parameters separately from caller variables.
- Apply assignments through reference parameters to the connected caller variables.
- When the subroutine finishes, continue after the call with the updated caller state.
Suggested trace-table columns
| Stage | Argument | Parameter | Mode | Parameter value | Caller variable |
|---|---|---|---|---|---|
| Call begins | Record supplied data | Record receiving name | BYVAL or BYREF | Record local value or reference result | Record any changed caller state |
ENDPROCEDURE. Show the values visible
to the caller after control returns.
Worked Example: Calibrating a Sensor Record
A procedure receives a stored sensor reading, a calibration adjustment and a warning counter. It must update the caller’s reading and increase the warning count when the corrected reading is outside the preferred range.
Procedure definition
PROCEDURE CalibrateSensor(
BYREF Reading : INTEGER,
BYVAL Adjustment : INTEGER,
BYREF WarningCount : INTEGER
)
Reading ← Reading + Adjustment
IF Reading < 20 OR Reading > 75
THEN
WarningCount ← WarningCount + 1
ENDIF
ENDPROCEDURE
Main program
DECLARE StoredReading : INTEGER
DECLARE CalibrationChange : INTEGER
DECLARE Warnings : INTEGER
StoredReading ← 83
CalibrationChange ← -6
Warnings ← 4
CALL CalibrateSensor(
StoredReading,
CalibrationChange,
Warnings
)
OUTPUT "Corrected reading: ", StoredReading
OUTPUT "Warning count: ", Warnings
Interface mapping
| Position | Argument | Parameter | Mode | Initial connection or value |
|---|---|---|---|---|
| 1 | StoredReading |
Reading |
BYREF |
Refers to the caller variable containing 83 |
| 2 | CalibrationChange |
Adjustment |
BYVAL |
Receives the separate value -6 |
| 3 | Warnings |
WarningCount |
BYREF |
Refers to the caller variable containing 4 |
Trace
| Statement | StoredReading/Reading |
Adjustment |
Warnings/WarningCount |
|---|---|---|---|
| Call begins | 83 | -6 | 4 |
Reading ← Reading + Adjustment |
77 | -6 | 4 |
77 < 20 OR 77 > 75 |
Condition is true | -6 | 4 |
WarningCount ← WarningCount + 1 |
77 | -6 | 5 |
| Control returns | Caller sees 77 | Caller variable remains -6 | Caller sees 5 |
Output
Corrected reading: 77
Warning count: 5
Interactive: Parameter and Interface Visualiser
Select a scenario and trace how arguments are matched to parameters. The visualiser distinguishes copied values from references connected to caller variables.
Common Mistakes and Misconceptions
- Calling an argument a parameter: arguments appear in calls; parameters appear in headers.
- Matching by identifier name: arguments are matched to parameters by position.
- Supplying the wrong number of arguments: the call does not satisfy the interface.
- Ignoring data types: an argument must produce a value compatible with its parameter.
- Assuming every argument must be a variable: value parameters may receive literals or expressions.
- Supplying a literal to BYREF: there is no caller variable for the procedure to update.
- Expecting BYVAL changes to affect the caller: the parameter contains a separate value.
- Expecting BYREF to create a separate copy: it refers to the caller variable.
- Using BYREF for every parameter: only variables that the procedure intends to update should normally be passed by reference.
- Passing function parameters by reference: functions should receive values and return one result.
- Confusing an argument with a return value: arguments enter a subroutine; a function’s return value leaves it.
- Tracing only inside the procedure: the final caller state must also be recorded.
Practice
Question 1: identify the terminology
PROCEDURE ShowMeasurement(
Label : STRING,
Value : REAL
)
CALL ShowMeasurement("Pressure", 31.6)
Identify the procedure header, parameters and arguments.
Question 2: positional matching
PROCEDURE DisplayRoute(
StartPoint : STRING,
EndPoint : STRING,
Distance : INTEGER
)
CALL DisplayRoute("Harbour", "Museum", 7)
State the value received by each parameter.
Question 3: incorrect order
CALL DisplayRoute(7, "Harbour", "Museum")
Explain why this call does not match the interface in Question 2.
Question 4: write a procedure interface
Write a procedure called ShowProduct that receives a product
name as a string and a price as a real number.
Question 5: trace BYVAL
PROCEDURE DoubleValue(BYVAL Number : INTEGER)
Number ← Number * 2
ENDPROCEDURE
Value ← 9
CALL DoubleValue(Value)
State the value of Number inside the procedure and the value
of Value after the call.
Question 6: trace BYREF
PROCEDURE DoubleValue(BYREF Number : INTEGER)
Number ← Number * 2
ENDPROCEDURE
Value ← 9
CALL DoubleValue(Value)
State the value of Value after the call and explain the
difference from Question 5.
Question 7: choose passing modes
A procedure receives a price, a discount percentage and a variable in which it must store the discounted price. Choose suitable passing modes and write the header.
Question 8: valid BYREF argument?
Explain why this call is unsuitable when
Count is a reference parameter:
CALL ResetCount(0)
Question 9: function interface
Write a function called CalculateEnergy that receives power
and time as real parameters and returns a real result.
Question 10: mixed trace
PROCEDURE UpdateValues(
BYREF First : INTEGER,
BYVAL Increase : INTEGER,
BYREF Second : INTEGER
)
First ← First + Increase
Second ← Second + First
ENDPROCEDURE
X ← 5
Y ← 8
CALL UpdateValues(X, 3, Y)
Trace the procedure and state the final values of X and
Y.
Question 11: improve the interface
PROCEDURE P(BYREF A : INTEGER,
BYREF B : INTEGER,
BYREF C : STRING)
The procedure only reads A and C, but updates
B. Rewrite the header using more suitable passing modes and
meaningful identifiers.
Question 12: explain the interface
PROCEDURE RecordDelivery(
BYREF StockLevel : INTEGER,
BYVAL Delivered : INTEGER
)
Explain what the interface communicates to a programmer calling the procedure.
Show suggested answers
Question 1
-
Header:
PROCEDURE ShowMeasurement(Label : STRING, Value : REAL) - Parameters:
LabelandValue - Arguments:
"Pressure"and31.6
Question 2
StartPointreceives"Harbour".EndPointreceives"Museum".Distancereceives7.
Question 3
The first parameter requires a string but receives the integer 7. The remaining values are also shifted into the wrong positions.
Question 4
PROCEDURE ShowProduct(
ProductName : STRING,
Price : REAL
)
OUTPUT ProductName, ": ", Price
ENDPROCEDURE
Question 5
Inside the procedure, Number becomes 18. The caller variable
Value remains 9 because it was passed by value.
Question 6
Value becomes 18 because Number refers to the
caller variable.
Question 7
PROCEDURE CalculateDiscount(
BYVAL OriginalPrice : REAL,
BYVAL DiscountPercentage : REAL,
BYREF DiscountedPrice : REAL
)
Question 8
The literal 0 is not a caller variable and therefore cannot be updated through a reference parameter. A variable should be supplied.
Question 9
FUNCTION CalculateEnergy(
Power : REAL,
Time : REAL
) RETURNS REAL
RETURN Power * Time
ENDFUNCTION
Question 10
First ← 5 + 3
First ← 8
Second ← 8 + 8
Second ← 16
Because First and Second are reference
parameters, the final caller values are:
X = 8 and Y = 16.
Question 11
One possible improved header is:
PROCEDURE UpdateRecord(
BYVAL InputNumber : INTEGER,
BYREF ResultNumber : INTEGER,
BYVAL Description : STRING
)
Question 12
The caller must supply two integers in the stated order.
StockLevel refers to a caller variable that the procedure may
update. Delivered receives a separate input value and changes
to that parameter would not affect its argument.
Review
| Concept | Key idea |
|---|---|
| Argument | A value or expression supplied in a subroutine call |
| Parameter | A named variable listed in the subroutine header |
| Header | Identifies the subroutine and its parameter requirements |
| Interface | Name, parameters, types, modes and any function return type |
| Positional matching | Each argument supplies the parameter in the same position |
BYVAL |
The parameter receives a separate value |
BYREF |
The parameter refers to a caller variable |
| Default passing mode | Passing by value is assumed when no mode is stated |
| Function parameters | Passed by value; the function returns one result |