Note 5: Pass by Address, Pass by Reference

 

References:

Three sides of a reference:

  1. A reference is an alias for a variable.
  2. A reference has special properties that determine how it is evaluated.
  3. A reference has special uses.

 

Reference as Alias:

Reference is a compiler object that is set-aside storage space.  This makes it a separate entity from the compiler.  It is not a copy of the variable to which it refers.  It is the same variable, just under a different name.

 

 

Properties of a Reference:

First, you cannot manipulate a reference as an independent entity.  This makes sense based on our definition of a reference as an alias.  A reference has no storage space in its own right; it is just a different name for a variable.  What does this mean?  It means that any operation you try to do on a reference would really be done to the compiler object it points to.  Take the address of a reference and you get the address of the variable it refers to.  Assign to a reference and you are assigning to the variable it refers to.  Another good proof of this property is that you cannot create an array of references.  A compiler could not let your do this because doing so violates the concept of an array.  An array is a group of like objects.

 

Second, your must initialize a reference.  As an alias to some other variable, an alias cannot exit on its own.  It is nothing without something to ※refer to§.  You are allowed to declare a reference in function return values and function parameters because the references are automatically initialized to arguments from the calling function.

 

Third, a reference is a constant bye definition.  After you initialize a reference, you cannot change its value.  Since a reference is not even a compiler object, it cannot hold a value, and therefore it is ludicrous even to think about changing its value.  References are nothing more than shorthand notations that are simpler and more readable than pointers.

 

 

Uses of a Reference:

References are used in three primary ways:

  1. A reference can be used in passing arguments to a function by reference.
  2. A reference can be returned by a function.
  3. An independent reference can be created (It is available and often used to demonstrate references).

 

 

 

 

Argument Type Table:

 

Pass by Value

Pass by Reference

Pass by Address

Constant

X

 

 

Variable

X

X

X

Pointer

X

X

X

Array Name

 

 

X

Array Elements

X

X

X

Expression

X

 

 

Function Call

X

 

 

Function Name

 

 

X

 

 

Program Example:

Pass by Value:

// Function does not change value of arguments 每 passby_value (a, b)

short   passby_value (short x, short y)

{

            short   temp;

 

            if(x < y)

            {

                        temp = x;

                        x = y;

                        y = temp;

            }

            return x 每 y;

}

 

 

Pass by Reference:

// Function changes the value of the arguments 每 passby_reference (a, b)

short   passby_reference (short &x, short &y)

{

            short   temp;

 

            if(x < y)

            {

                        temp = x;

                        x = y;

                        y = temp;

            }

            return x 每 y;

}

 

// Function changes the value of the arguments (pointers) 每 pass_ptr_by_reference(ptra,

// ptrb)

short   pass_ptr_by_reference (short *& x, short *& y)

{

            short   *temp_ptr;

 

            if(*x < *y)

            {

                        temp_ptr = x;

                        x = y;

                        y = temp_ptr;

            }

            return *x 每 *y;

}

 

 

Pass by Address:

// Function changes the value of the arguments 每 passby_address1 (&a, &b)

// Function changes the value at the address stored in the pointers 每 pointers 每

// passby_address1 (ptra, ptrb)

short   passby_address1 (short * const x, short * const y)

{

            short   temp;

 

            if(*x < *y)

            {

                        temp = *x;

                        *x = *y;

                        *y = temp;

            }

            return *x 每 *y;

}

 

// The values of the local variables are changed, but there is no effect on the arguments 每

// passby_address2 (&a, &b) or the value at the address stored in the pointers 每

// passby_address2 (ptra, ptrb)

short   passby_address2 (short *x, short *y)

{

            short   *temp_ptr;

 

            if(*x < *y)

            {

                        temp_ptr = x;

                        x = y;

                        y = temp_ptr;

            }

            return *x 每 *y;

}

// Function changes the value of the arguments (pointers) 每 pass_ptr_by_address1 (&ptra,

// &ptrb)

// Function changes the value at the address stored in the pointers 每 pass_ptr_by-address1 // (ptr_ptra, ptr_ptrb)

// values of ptra and ptrb are changed

// values of a and b are not changed

// values of ptr_ptra and ptr_ptrb are not changed

short   pass_ptr_by_address1 (short **x, short **y)

{

            short   *temp_ptr;

           

            if(**x < **y)

            {

                        temp_ptr = *x;

                        *x = *y;

                        *y = temp_ptr;

            }

            return **x 每 **y;

}

 

// Function changes the value at the address stored in the pointer 每 pass_ptr_by_address2

// (&ptra, &ptrb)

// Function changes the value at the address stored in the pointers to pointers 每

// pass_ptr_by-address2 (ptr_ptra, ptr_ptrb)

// values of a and b are changed

// values of ptra and ptrb are not changed

// values of ptr_ptra and ptr_ptrb are not changed

short   pass_ptr_by_address2 (short **x, short **y)

{

            short   temp;

           

            if(**x < **y)

            {

                        temp = **x;

                        **x = **y;

                        **y = temp;

            }

            return **x 每 **y;

}

 

// The values of the local variables are changed, but there is no effect on the arguments or

// values at the address stored in the arguments

short   pass_ptr_by_address3 (short **x, short **y)

{

            short   **temp_ptr_ptr;

           

            if(**x < **y)

            {

                        temp_ptr_ptr = x;

                        x = y;

                        y = temp_ptr_ptr;

            }

            return **x 每 **y;

}

 

 

Summary:

short    np, *p, **pp, ***ppp;   //np is non-pointer vairable

p = &np;                                    //p is pointer variable which has address of np

pp = &p;                                   //pp is pointer variable which has address of p

ppp = &pp;                               //ppp is pointer variable which has address of pp

 

 

 


                                                      

     ppp              pp               p               np

   

Argument and Parameter Table:

 

Pass by Reference

Pass by Value #

Pass by Address #

Parameter

NP

P

PP

PPP

NP

P

PP

P

PP

Argument

np

p

pp

ppp

np

*p

**pp

***ppp

p

*pp

**ppp

pp

*ppp

&np

p

*pp

**ppp

&p

pp

*ppp

Variable which can be changed

np

np

p

np

p

pp

np

p

pp

ppp

none

np

np

p

np

np

p

#  Passing the value of the argument to the parameter; the value of argument may be a non-pointer or pointer (address).