Call by Address
Call by Address
Call by Address
In call by address, instead of passing the actual values of the actual argument we pass addresses of actual values.
Whenever we deal with addresses, we must know how to handle them. That’s why before discussing call by address, we
will briefly discuss pointers that handle addresses.
Introduction to Pointers
We all know that the internal data storage of a computer is a memory unit. Memory unit is an ordered sequence
of memory cells, each capable of containing a piece of data. Each memory cell has a distinct address that can be
used to refer to it when data is stored in it or retrieved from it.
The addresses of memory depend upon its capacity. For a 640 KB of memory we have addresses from 0 to
655,359; for 1 MB of memory we have addresses from 0 to 1,048,575 & so on. Since the memory holds data
and instructions, therefore when our program is loaded into memory it occupies some space in memory. It
means that every variable and every function starts at a particular address.
//Program–8.cpp
#include
Void main()
{
int i=4, j=8;
cout<< i << j;
}
Here the addresses of variable i and j are 62800 and 62802 respectively. And the value 4 and 8 are stored at the
addresses 62800 and 62802 respectively. Program 9.cpp illustrates this concept.
// Program –9.cpp
#include
void main()
{
int i=4, j=8;
cout << “\n Value=”<< i << “\tAddress=”<< &i;
cout << “\n Value=”<< j << “\tAddress=”<< &j;
}
The output of this program is:
Value = 4 Address = 0x8facfff4
Value = 8 Address = 0x8facfff2
The output represents the addresses in hexadecimal form, as indicated by the prefix 0x before each address. One
main point to note that their addresses may vary during particularly in multi user computer system.
Pointer Declaration :
As we store integer values into integer variables, we can also store addresses of variables in a special type of
variables, known as pointer variables. Thus a pointer variable is defined as the variable that holds an address of
a memory location. The syntax of the declaration pointer variable is
datatype * pointer_var_name;
The datatype is any valid C++ data type and pointer_var_name is the name of the pointer variable name. Here
the asterisk (*) operator implies pointer to. The result of pointer operator, *, does the reverse of address operator
&. It means that the pointer operator (*) returns the value of variable stored at the address following it. Thus to
access the value stored at any address we will use pointer operator. Program 10.cpp illustrates this concept:
void main()
{
int i=4;
int *iptr;
iptr = &i;
cout << “\n Value = ”<< i << “\tAddress = ”<< &i;
cout << “\n Value = ” << *iptr << “\tAddress = ” <
}
The output of this program is as:
Value = 4 Address = 0x8facfff4
Value = 4 Address = 0x8facfff4
In this program, the statement
int *iptr;
means that iptr is a pointer variable that contains an address of variable type int, in other words iptr acts as a
pointer to integer. Thus if iptr contains an address then *(iptr) contains a value stored at this address.
That is why in this program
*(iptr) results in 4.
Like integer pointer we can also have pointers for other data type such as char, float or even for a user defined
data type as:
char *cptr;
float *fptr;
long *lptr;
Like ordinary variables, we can also define multiple pointers in one line as:
int *iptr1, *iptr2, *iptr3;
While using pointer variables one should remember that we store the address of a data type into the pointer of
same data type. We can not store the address of a variable of one type into another type of pointer variable. It
means that integer pointer can hold an address of integer variable, float pointer can hold an address of float
variable and so on.
Now we will see how to use pointers in call by address functions. In cal by address we pass addresses of actual
arguments to the called function. These addresses are stored into formal arguments, which are nothing other
than pointer variables. Now whatever changes are made into the formal arguments they are directly reflected to
the actual arguments..
// Program –11.cpp – Call by address
#include
void swapadd (int *, int *);
void main ()
{
int a, b ;
cout << "\nEnter two numbers = " ;
cin >> a >> b;
cout << "Before calling swapadd() function.";
cout << "\na = " << a;
cout << "\nb = " << b;
swapadd (&a, &b ) ;
cout << "\nAfter calling swapadd() function.";
cout << "\na = " << a;
cout << "\nb = " << b ;
}
void swapadd(int *aa, int *bb)
{
int temp;
temp = (*aa);
(*aa) = (*bb);
(*bb) = temp;
}
In program 11.cpp, we pass the addresses of variables a and b to the functions swapadd(). When the function
swapadd() is invoked, the addresses of a and b are copied into the integer pointers aa and bb respectively.
Here is the output of this program….
Enter two number = 10 20
Before calling swapadd() function.
a = 10
b = 20
After calling swapadd() function.
a = 20
b = 10
Call by Reference
In call by reference, a function passes a reference as an argument to another function. In this case the called
function works on the callers copy of parameters and not on a local copy. Before the discussion of call by
reference we must know what is a reference.
Introduction to Reference
A reference is referred to as an alias or synonym, that is an alternate name for another variable. Like pointers,
the reference enables us to pass large amount of data without the overhead of copying them. Of course pointer
also is an important feature of C and C++, but sometimes it may trouble you and even a good programmer for
some complex operations.
References are much like pointers. You can do anything with a reference that you can do with a pointer. The C+
+ reference variables can give you same type of problem until you understand them. However it has certainly
some plus points over pointers.
A reference is indicated following the type specifier with the address-of & operator or you can say the &
operator identifies a reference variable. A reference must be initialized when it is declared as in the following
example:
int a=10;
int &b = a;
Here we have declared an integer variable, a, that has another name, b. Note that a reference can not be made to
refer to another variable (this is why it must be initialized. If you make any change to a reference then that
change is actually applied to the variable to which the reference refers. Therefore now all references to either
name have the same effect.
For example,
b+= 5;
adds 5 to a, the variable referred to by b. Another main point to note that each definition of a reference must be
preceded by the address of operator. For example,
int &x = a, y = b;
defines one reference and one variable. Let us take a simple example that illustrates the concept of a reference:
// Program – 12.cpp – Use of reference
#include
void main()
{
int a = 20 ;
int & b = a;
cout << “\n a = “ << a << “ b = “ << b ;
b = 40;
cout << “\n a = “ << a << “ b = “ << b ;
a = 60;
cout << “\n a = “ << a << “ b = “ << b ;
}
These above initializations are completely invalid for non-const references and thus they result in compile-time
errors. When is initialized to a variable type then the compiler must generate a temporary object that the
reference actually address but unfortunately user has no access to it. Thus the following two statements:
float x = 25.75;
const int & a = x;
are internally transformed as:
float x = 25.75;
int temp = x;
const int &a = temp;
Aso the statement
const int &c = 204;
is also interpreted as:
int temp = 204;
const int &c = temp;
Now we see how it helps in function swapref().
// Program – 14.cpp: Call by reference
#include
void swapref(int &, int &);
void main()
{
int a, b;
cout << “\nEnter two numbers = ” ;
cin >> a >> b ;
cout << "Before calling swapref() function.";
cout << “\na = ”<< a << “\tb = ”<< b;
swapref(a, b);
cout << "After calling swapref() function.";
cout << “\na = ” << a << “\tb = ” << b;
}
void swapref(int &aa, int &bb)
{
int temp;
temp = aa;
aa = bb;
bb = temp;
}
The output of this program is:
Enter two numbers = 5 10
Before calling swapref() function.
a = 5 b = 10
After calling swapref() function.";
a = 10 b = 5
Naturally the above program looks very simple and convenient way than call by address.
The const Reference :
In program 14.cpp, the swapref() function modifies the caller’s variables because the parameters are references
to those variables. However in certain situations, a function is restricted to modify caller’s referenced variable.
To handle this, we declare such arguments as const.
The const reference arguments ensures the caller that the called function can view them but can not modify the
values in the referenced arguments. The const references are treated as read only arguments. In program 14.cpp
if you use the following reference function.
void swapref(const int &aa, const int &bb)
{
int temp;
aa = temp;
aa = bb;
bb = temp;
}
You would certainly get an error message, say:
Can not a const object
Returning a Reference
We have already studied that how to pass a reference to a function as a parameter. However you also can return
a reference from a function. In such cases when a function returns a reference the function call can exist in any
context in which a reference can exist, including on the receiving side of an assignment. Program 15.cpp
illustrates this concept.
// Program - 15.cpp
#include
int &max(int &, int &);
void main()
{
int x, y;
cout<<”\n Enter any two numbers = ”;
cin >> x >> y;
int &z=max(x, y);
{
inside the body , the aguement is to be used as any other variable(not as pointer variable)
}
function call
function_name(arguement name);
//the variable is passed like any other variable of its data type and as an address
Example :: SWAP program revisited
#include<iostream>
using namespace std;
void swap_ref(int &a,int &b);
void swap_val(int a,int b);
int main()
{
int a=3,b=6;
printf(“\\na=%d b=%d”,a,b);
swap_val(a,b);
printf(“\\na=%d b=%d”,a,b);
swap_ref(a,b);
printf(“\\n a=%d b=%d”,a,b);
return 1;
}
void swap_ref(int &a, int &b)
{
//function acceptsa reference
a=a+b;
//to original parameter variable
b=a-b;
a=a-b;
}
void swap_val(int a, int b)
{
a=a+b;
b=a-b;
a=a-b;
}
OUTPUT:
a=3 b=6
a=3 b=6
a=6 b=3