Note 5: Pass by
Address, Pass by Reference
References:
Three sides of a reference:
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:
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).