Lesson 11.5. Pointers as function argument in C

In C, there are two methods to pass variables as parameters in a function:

Call by value

This is the "classic" technique presented in lesson 8.1 on functions. With this approach, the transmitted variable is copied into the local variable of the the function. Consider the following function:

void fct(int arg) {
  // Display the pointer address of the argument
  printf ("Adsress of arg = %p\n", &arg);
}
// Create a variable named var and display its address
int var=28;
printf ("Addresse of var = %p\n", &var);

// Call the function
fct(var);

When we run this program, we see that the variable var does not have the same address as the variable arg, local to the function. So there are two distinct variables at two different addresses. Their only link is when the function is called: the value of var is copied into arg. This is the reason why we talk about "Call by value". The function fct() cannot modify the variable var.

Call by reference

The second approach is to pass the address of the variable to the function (instead its value). By doing so, the function can modify the content of the variable, even if it is local to another function. Consider the following two functions:

void value(int arg) { arg++; }
void reference(int *arg) { (*arg)++; }

Now let's analyze the following code:

int var1=5,var2=5;

// Call by value
value(var1);
// Display 5: var1 is not modified by the function
printf ("Value => var1 = %d\n", var1);

// Call by reference
reference(&var2);
// Display 6: var2 is modified by the function
printf ("Reference => var2 = %d\n", var2);

When passing by value, the value() function cannot change the content of the variable (var1). On the other hand, when passing by reference, the function variable() can modify the content of the arguments (var2): As it is the address that is passed to the function, the function can modify the content of the variable.

variable => var1 = 5
valeur   => var1 = 6

This technique is used, for example, to overcome the limit on the number of parameters that can be returned by a function with return (i.e. 1). This mechanism is used in the scanf() function so that the variable can be modified by the function.

scanf("%d", &val);
            ^
            Call by reference

Exercise

Exercise 1

Write a swap() function that swaps the contents of two variables::

// Swap the contents of a and b
void swap(int *a, int *b);

Here is the expected output:

Before: x=7 y=8
After : x=8 y=7

Exercise 2

Write a function percent() that receives as parameter val, a float called per value.

After calling the function, the variable passed in parameter must be between 0 and 100. Here are some examples :

Enter a percentage value: 12.5
12.50% is valid
Enter a percentage value: 156.78
It's too big, I replaced it with 100.00%.

Exercise 3

The main() function wait for two parameters:

int main(int argc, char *argv[]) 

Under Linux, when you type the file listing command ln -a -s in a terminal, you pass the arguments -a and -s to a main() function that was programmed in C.

> ls -a -l
total 20
drwxr-xr-x 1 runner runner   20 Oct 30 16:27 .
drwxr-xr-x 1 runner runner 4096 Oct 30 16:23 ..
-rwxr-xr-x 1 runner runner 8392 Oct 30 16:27 main
-rw-r--r-- 1 runner runner  515 Oct 30 16:27 main.c

Write a program that displays the number and contents of the arguments of the function main():

> ./main
1 argument(s) detected
argv[0] = ./main
> ./main -f test.txt
3 argument(s) detected
argv[0] = ./main
argv[1] = -f
argv[2] = test.txt

Exercise 4

Write a function that calculates the roots of a second degree polynomial and returns the discriminant:

double roots(double a, double b, double c, double * r1, double * r2);

Write a main program that asks the user to enter the coefficients of the polynomial before displaying its roots:

Enter the coefficient a : 2.5
Enter the coefficient b : 4.6
Enter the coefficient c : 18.7
 -> Complex roots
Enter the coefficient a : 1
Enter the coefficient b : 4
Enter the coefficient c : 4
 -> Two identical roots: x1 = x2 =-2.00
Enter the coefficient a : 1.4
Enter the coefficient b : 18.5
Enter the coefficient c : 2
 -> Two roots: x1=-0.11 and x2=-13.11

Quiz

This function accepts what type of parameter?

void fct(int v);
Check Bravo! That's not a pointer expected in the function, it is call by value. Try again...

This function accepts what type of parameter?

void fct(int *v);
Check Bravo! This time it is a pointer that is expected. Try again...

From a purely syntactical point of view, what types of variables can be passed to the following function?

void uppercase(char *arg);
Check Bravo! A pointer can point to a variable or an array. Try again...

What does the following code display?

void addTwo(int i) { i=i+2; }
int main(void) {
  int var=5;
  addTwo(var);
  printf ("var = %d", var);
}
Check Bravo! The argument is called by value, it can't be modified by the fonction. Try again...

What does the following code display?

void addTwo(int *i) { *i=*i+2; }

int main(void) {
  int var=5;
  addTwo(&var);
  printf ("var = %d", var);
}
Check Bravo! This time the argument is called by reference, the function can modify the value of the variable. Try again...

See also


Last update : 11/28/2022