Parameter-Passing Modes


Contents


Overview

In Java, all parameters are passed by value. In C++, a parameter can be passed by:

  1. value,
  2. reference, or
  3. const-reference
Each parameter's mode is determined by the way it is specified in the function's header (the mode is the same for all calls to the function). For example: Parameter a is a value parameter, b is a reference parameter, and c is a const-reference parameter.

Value Parameters

When a parameter is passed by value, a copy of the parameter is made. Therefore, changes made to the formal parameter by the called function have no effect on the corresponding actual parameter. For example:

In this example, f's parameter is passed by value. Therefore, although f increments its formal parameter n, that has no effect on the actual parameter x. The value output by the program is 2 (not 3).

Note that if a pointer is passed by value, then although the pointer itself is not affected by changes made to the corresponding formal parameter, the object pointed by the pointed can be changed. For example:

In this example, f's parameter is passed by value. Therefore, the assignment p = NULL; in f has no effect on variable q in main (since f was passed a copy of q, not q itself). However, the assignment *p = 5: in f, does change the value pointed to by q. To understand why, consider what happens when the example program runs:

Reference Parameters

When a parameter is passed by reference, conceptually, the actual parameter itself is passed (and just given a new name -- the name of the corresponding formal parameter). Therefore, any changes made to the formal parameter do affect the actual parameter. For example:

In this example, f's parameter is passed by reference. Therefore, the assignment to n in f is actually changing variable x, so the output of this program is 3.

When you write a function whose purpose is to compute two or more values, it makes sense to use reference parameters (since a function can return only one result). For example, if you want to read a list of integers from a file, and you want to know both how many integers were read, as well as the average value that was read, you might use a function like the following:

Another common use of reference parameters is for a function that swaps two values: This is useful, for example, in sorting an array, when it is often necessary to swap two array elements. The following code swaps the jth and kth elements of array A:

Const-Reference Parameters

Another reason to use reference parameters is when you don't want the function to modify an actual parameter, but the actual parameter is very large, and you want to avoid the overhead of creating a copy. Of course, this only works if the function does not modify its formal parameter. To be sure that the actual parameter is not "accidentally" modified, you should use a const-reference parameter. Declaring the parameter to be const tells the compiler that it should not be changed; if the function does change the parameter, you will get a compile-time warning (possibly an error on some systems). For example:

The potential use of a const-reference parameter is the reason why member functions that do not modify any data members should be declared const. For example, suppose that the IntList Print member function was not declared const. Then the following code would cause a compile-time error: Because L is a const-reference parameter, it is the compiler's job to be sure that L is not modified by f (and that means that no data members of L are modified). The compiler doesn't know how the Print function is implemented; it only knows how it was declared, so if it is not declared const, it assumes the worst, and complains that function f modifies its const-reference parameter L.

Array Parameters

Another unfortunate thing about C++ arrays is that they are always passed by reference (even though you don't declare them to be reference parameters). For example:

Although f's parameter looks like it is passed by value (there is no &), since it is an array it is actually passed by reference, so the assignment to A[0] is really assigning to B[0], and the program prints 5 (not 2).

If you want to pass an array by value, you should use a vector, not a regular C++ array (see the last section in the notes on C++ classes for information about vectors).


TEST YOURSELF NOW

  1. Consider the following code segment. What is output when function Print is called?

    A. 0 1 2 0 1 2
    B. 3 0 0 3 0 0
    C. 0 1 2 3 0 0
    D. 3 0 2 2 0 2
    E. 3 0 0 0 0 0

  2. A function called Sqrt, which is intended to compute and return the square root of its integer parameter, has been written. When the function is tested, it is observed that, although the correct value is returned, the argument passed to Sqrt is always zero after the function call. Which of the following is the most likely explanation for this problem?

    A. Sqrt is written using recursion; it should be written using iteration.
    B. Sqrt is written using iteration; it should be written using recursion.
    C. Sqrt's parameter is a value parameter; it should be a reference parameter.
    D. Sqrt's parameter is a reference parameter; it should be a value parameter.
    E. Sqrt's parameter is a const reference parameter; it should be a value parameter.

  3. Consider the following program. What happens when this program is compiled and executed?

    A. There is a compile-time error because in the call Sum(x, y, y), variable y is passed both by value and by reference.
    B. There is a run-time error because in the call Sum(x, y, y), variable y is passed both by value and by reference.
    C. The program compiles and executes without error. The output is: 2 3
    D. The program compiles and executes without error. The output is: 6 9
    E. The program compiles and executes without error. The output is: 2 15

    Questions 4 and 5 refer to the following function.

  4. Which of the following best explains what function Mystery does?

    A. Always returns true.
    B. Always returns false.
    C. Determines whether vector A really is sorted.
    D. Determines whether vector A contains any duplicate values.
    E. Determines whether all values in vector A are the same.

  5. Which of the following best explains why A is a reference parameter?

    A. A may be modified by function Mystery; thus, it must be a reference parameter.
    B. A is indexed by function Mystery; thus, it must be a reference parameter.
    C. A's size member function is used by function Mystery; thus, it must be a reference parameter.
    D. It is more efficient to pass A by reference than by value.
    E. There is no reason for A to be a reference parameter.


Answers:
1. D
2. D
3. E
4. D
5. D