• C Programming Video Tutorials

Function call by reference in C



In C, a function can be called from any other function, including itself. There are two ways in which a function can be called − a) call by value and b) call by reference. By default, the call by value mechanism is employed. In this chapter, we shall learn about the mechanism of calling a function by reference.

Syntax

type function_name(type *var1, type *var2, . . .)

We must know some terminologies to understand how the call by reference method works.

Formal arguments − A function needs certain data to perform its desired process. When a function is defined, it is assumed that the data values will be provided, in the form of parameter or argument list inside the parenthesis in front of function name. These arguments are the variables of a certain data type.

Actual arguments − When a certain function is to be called, it should be provided with the required number of values of the same type and in same sequence as used in its definition.

Address operator − In C, a variable is named memory location. When a variable declared, the compiler allocates a random location in the memory and internally identifies the location with the user−defined name. To fetch the address at which the variable has been created, the & operator is provided.

For example

int x =10;
printf("x: %d address of x: %d", x, &x);

This will print the value of x and its address.

Pointer − A pointer is a variable that stores the address of another variable. To declare a pointer variable, its name is prefixed with * symbol. The type of the pointer variable and its host variable must be same. The address is assigned with the & operator. The dereference operator * is used with the pointer. It fetches the value of a variable whose address is assigned to the pointer.

int x =10;
int *y = &x;
printf("x: %d address of x: %d\n", x, &x);
printf(" address of x: %d\n", y);
printf("Value at address in y: %d\n", *y);

When a function is called by reference, the address of the actual argument variables passed, instead of their values.

Let us define add() function that receives the references of two variables

int add(int *x, int *y){
   int z = *x+*y;
   return z;
}

When such a function is called, we pass the address of the actual argument. Let us call add() function by reference from inside main() function.

Example

#include <stdio.h>

/* function declaration */
int add(int *, int *);

int main(){
   int a=10, b=20;
   int c = add(&a, &b);
   printf("addition : %d", c);
}

int add(int *x, int *y){
   int z = *x + *y;
   return z;
}

Output

addition :30

The main() function passes the address of a and b to add(). Addresses of a and b are assigned to the pointer variables x and y. Inside the add() function, the statement

z = *x + *y;

Remember that x stores address of a. The dereference operator in *x and *y fetches the values of a and b respectively, hence z is the addition of a and b in main() function.

Let us understand in more detail how the call by reference mechanism works, with the help of the following example that interchanges value of two variables

Swap values with call by reference

The following function receives the reference of two variables whose values are to be swapped.

/* function definition to swap the values */
int swap(int *x, int *y) {

   int z;
   z = *x;   /* save the value at address x */
   *x = *y;  /* put y into x */
   *y = z;   /* put z into y */
  
   return 0;
}

The main() function has two variables a and b, their addresses are passes as arguments to swap() function.

#include <stdio.h>
int swap(int *x, int *y);
int main () {

   /* local variable definition */
   int a = 10;
   int b = 20;
 
   printf("Before swap, value of a : %d\n", a );
   printf("Before swap, value of b : %d\n", b );
 
   /* calling a function to swap the values */
   swap(&a, &b);
 
   printf("After swap, value of a : %d\n", a );
   printf("After swap, value of b : %d\n", b );
 
   return 0;
}

Assume that the variables a, and b in main() function are allotted locations with memory address 100 and 200 respectively. As their address is passed to x and y (remember that they are pointers), the variables x, y and z in swap() functions are created at addresses 1000, 2000 and 3000 respectively.

Inside the swap in C

Since x and y stores address of a and b, x becomes 100 and y becomes 200, as the above figure shows. Inside the swap() function, the first statement

z = *x

Causes the value at address in x to be stored in x (which is 10). Similarly,

*x = *y;

The value at address in y (which is 20) is stored in the location whose pointer is x Lastly,

*y = z;

Assigns the z to the variable pointed to by y, which is b in main(). The values of a and b now get swapped. You can refer to the following figure to understand visually how this works.

Understand Visually how this works in C

The result of the program when executed is −

Before swap, value of a : 10
Before swap, value of b : 20
After swap, value of a : 20
After swap, value of b : 10

Mixed call

You can use a function calling mechanism that is a combination of call by value and call by reference. It can be termed as mixed calling mechanism, where some of the arguments are passed by value and others by reference.

A function in C can have more than one arguments, but can return only one value. The call by reference mechanism is a good solution to overcome this restriction.

Example

In the following example, the calculate() function receives an integer argument by value, and two pointers where its square and cube are stored.

#include <stdio.h>
#include <math.h>
/* function declaration */
int calculate(int, int *, int *);

int main(){
   int a=10;
   int b, c;
   calculate(a, &b, &c);
   printf("a: %d square of a: %d cube of a: %d", a, b, c);
}

int calculate(int x, int *y, int *z){
   *y  = pow(x,2);
   *z = pow(x, 3);
   return 0;
}

Output

a: 10 square of a: 100 cube of a: 1000

Call by reference mechanism is widely used when a function needs to perform memory−level manipulations such as controlling the peripheral devices, performing dynamic allocation etc.

c_loops.htm
Advertisements