C Language

To share this page click on the buttons below;

Passing arguments by reference

The first "application" of pointers we are going to see is passing arguments functions by reference. Remember? When you use a variable as an argument of a function you are passing just the value of the variable, not the variable itself or (which is the same) a copy of the variable.

That means that any operation you make on that variable within the function is made just on the copy and it has no effect on the variable outside the function. That works fine, but what if you actually want to change the outer variable? In this case you need to pass the argument of the function by reference: that can be accomplished using pointers.

Argument by reference

When you pass an argument by reference you need to declare the argument of the function as a pointer. You want your function to modify an integer variable passed as argument, then your function must have a pointer to an integer as argument. In the same way if you want your function to be able to change a double variable, the argument of the function must be a pointer to a double. And so on for every other type.

The following short program is aimed to illustrate the concept:

#include <stdio.h>


int increment_by_value(int a);
int increment_by_reference(int *a);

int increment_by_value(int a) {
   a = a + 1;
   return a;
}

int increment_by_reference(int *a) {
   *a = *a + 1;
   return *a;
}

int main(void) {

   int val = 5;
   int result = 0;

   printf("Program to demonstrate passing by reference\n\n");

   /* Initial value of a */
   printf("Initial value of val = %i\n\n", val);

   printf("Using increment by value\n");
   result = increment_by_value(val);
   printf("  result = %i, val = %i\n\n", result, val);

   printf("Using increment by reference\n");
   result = increment_by_reference(&val);
   printf("  result = %i, val = %i\n", result, val);

   return 0;
}

The example is very simple, there are 2 functions which are supposed to do the same thing: incrementing the integer value passed as argument. The first function is increment_by_value and it takes an integer variable as argument, this function uses the passing by value mechanism. When this function is called, a copy of the variable val is made and put into the function scope, so that the variable a within the function has the same value of val, but they are two completely different variables. Inside this function a is incremented and then the result of the increment is returned. What happened to the variable val once increment_by_value is called? Nothing of course, because the function just uses a copy of the value of the variable. In fact when we print the value of val after we used it as argument of the function we can see that its value did not change, although the function did really increment the value we passed as we can see printing the result.

Turning to the increment_by_reference function we need to note that the argument is no more an integer variable, but a pointer to to an integer variable, then we have to also notice that when we call the function at line 32 we do not pass anymore the variable, but its address (that is accomplished by using the operator &). From now on things are going to work in the same way, a copy of the address (that is a number) is passed to the function, but this is a pointer pointing to the original val variable and that is the trick: now the pointer can access to the actual value of val using the operator *. With the pointer you have access to values that are outside the scope of the function because you have an "handle" (the pointer itself) to access them. The result of this function is the same than the previous one, but now the content of the variable val has been changed thanks to the function call.

I hope the following statement will not be confusing: the increment_by_reference works exactly the same as increment_by_value, always a copy of the argument value is passed to the function, but in the case of increment_by_reference the use of pointer makes the trick: you access the variable through its address, that allows to access the value of the variables "outside" of the scope of the function itself.

Performances observations

Suppose that you have a large structure, let us suppose that this structure is 356 bytes long (that is just a made up number), furthermore suppose that you need to use a function to make some processing on that structure. If you use the pass by value mechanism, every time you call this function a copy of the whole structure is made and passed to function: the bigger the structure the more the time and resources (mainly stack memory) you need.

Suppose now that you use the pass by reference mechanism(instead of the pass by value): just a copy of the pointer (which is an address) is made. The dimension of a pointer (as we have seen) is fixed and just depends on the processor, if we suppose to have a small 8 bits microprocessor, then once the function is called just 1 bytes is copied. That of course is not depending on the dimension of the structure. If the structure is 1 megabyte big and you pass the argument by reference this will require a copy of just one byte (on a 8 bits microprocessor, 4 bytes on a 32 bits microprocessor if you want). That requires less time and less resources of course and allows your program to perform better, but that comes at a certain price: if you use the pass by reference mechanism, it means that your function can change the content of the structure (and often that is exactly what you want to do), while if you use a pass by value you are guaranteed that the function cannot modify the values the structure is holding.

To share this page click on the buttons below;