# C++ Notes: Function Reference Parameters

Reference parameters are useful in two cases:

- Change values. Use a reference parameter when you need to change the value of an actual parameter variable in the call. When a function computes only one value it is considered a better style to return the value with the `return` statement. However, if a function produces more than one value, it is common to use reference parameters to return values, or a combination of the return value and reference parameters.
- Efficiency. To pass large structures more efficiently. This is especially common for passing structs or class objects. If no changes are made to the parameter, it is should be declared `const`.

## Reference parameters pass an address, not a value

When you declare a reference parameter, the function call will pass the memory address of where the actual parameter, instead of copying the parameter value into the formal parameter.

## Declare reference parameters with a &

To indicate a reference parameter, an ampersand (&) is written in the function prototype and header after the parameter type name. For example,

    void assign(int& to, int from) {
        to = from;  // Will change the actual parameter in the call.
    }

has two parameters, to is a reference parameter as indicated by the ampersand, and from is a value parameter. This ampersand must be in both the prototype and the function header.

## Example - Swap (bad solution)

Let's say you want to exchange the values in two arguments.

    int a = 5;
    int b = 10;

    swap(a,b);
    // If we want a=10 and b=5 as the result, how do we write the function?

Here's an example that does NOT work correctly, altho there is no error message.

    void swap(int x, int y) {  // BAD BAD BAD BAD BAD BAD BAD
        int temp = x; // temp is a local variable
        x = y;        // changes only local copy
        y = temp;     // changes only local copy
    }

Because x and y are value parameters, like local variables, changes to them have no effect on the calling functions arguments a and b.

## Example - Swap (good solution)

If the parameters are marked as reference parameters, the memory address of each argument is passed to the function. The function uses this address to both get and set the value. Here is `swap` written correctly. The only change is the addition of the & to the parameter declaration following the type.

    void swap(int& x, int& y) {
        int temp = x;  // temp is a local variable
        x = y;         // changes the actual parameter in the calling pgm.
        y = temp;      // changes the actual parameter in the calling pgm.
    }

## L-values required for actual reference parameters

An l-value is something that you can assign to. This name is short for left-value, referring to the kind of value that must be on the left side of an assignment statement. All actual reference parameters must have an l-value.

    swap(1, 2);         // BAD - literals don't have l-values.
    swap(x+5, c);       // BAD - numeric expressions don't have l-values.
    swap(x, y);         // OK - variables are l-values.
    swap(a[i], a[i+1]); // OK - array references are l-values.

It's easy to figure this out if you just think about what you can write on the left of an assignment; '1', '2', and 'x+5' are obviously not legal.