Cours 11.5. Passage de paramètres par pointeur

En C, il existe deux méthodes pour passer des variables en paramètre dans une fonction :

Passage de paramètres par valeur

C'est la technique "classique" présentée dans le cours 8.1 sur les fonctions. Avec cette approche, la variable transmise est copiée dans la variable locale à la fonctions. Considérons la fonction suivante :

void fct(int arg) {
  // Affiche l'adresse de l'argument du pointeur
  printf ("Adresse de arg = %p\n", &arg);
}
// Déclare une variable var et affiche son adresse
int var=28;
printf ("Adresse de var = %p\n", &var);

// Appel de la fonction
fct(var);

Lorsque l'on exécute ce programme, on s'aperçoit que la variable var n'a pas la même adresse que la variable arg, locale à la fonction. Il y a donc deux variables distinctes à deux adresses différentes. Leur seul lien est au moment de l'appel de la fonction : la valeur de var est copiée dans arg. C'est la raison pour laquelle on parle de passage par valeur. La fonction fct() ne peut pas modifier la variable var.

Passage de paramètres par variable

Aussi appelée passage par référence, cette seconde approche consiste à passer l'adresse de la variable (la référence). Ce faisant, la fonction peut modifier le contenu de la variable, même si elle est locale à une autre fonction.

Considérons les deux fonctions suivantes :

void valeur(int arg) { arg++; }
void variable(int *arg) { (*arg)++; }

Analysons maintenant le code suivant :

int var1=5,var2=5;

// Passage par valeur
valeur(var1);
// Affiche 5 : var1 n'est pas modifié par la fonction
printf ("valeur   => var1 = %d\n", var1);

// Passage par variable
variable(&var2);
// Affiche 6 : var2 est modifié par la fonction
printf ("variable => var2 = %d\n", var2);

Lors d'un passage par valeur, la fonction valeur() ne peut pas modifier le contenu de la variable transmise (var1). En revanche, lors d'un passage par variable, la fonction variable() peut modifier le contenu de la variable transmise (var2) : Comme c'est l'adresse qui est transmise à la fonction, celle-ci peut modifier le contenu de la variable.

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

Cette technique est utilisée, par exemple, pour contrer la limite du nombre de paramètres qui peuvent être retournés par une fonction avec return (c'est-à-dire 1). C'est ce mécanisme qui est utilisé dans la fonction scanf() pour que la variable puisse être modifiée par la fonction.

scanf("%d", &val);
            ^
            Passage par variable

Exercice

Exercice 1

Écrire une fonction permute() qui inverse le contenu de deux variables :

// Permutte le contenu de a et b
void permute(int *a, int *b);

Voici l'affichage escompté :

Avant : x=7 y=8
Après : x=8 y=7

Exercice 2

Écrire une fonction percent() qui reçoit en paramètre val un flottant par variable.

Après l'appel de la fonction, la variable passée en paramètre doit forcement être comprise entre 0 et 100. Voici quelques exemples escompté :

Entrez un pourcentage : 12.5
12.50% est valide
Entrez un pourcentage : 156.78
C'est trop grand, j'ai remplacé par 100.00%

Exercice 3

La fonction main() accepte deux paramètres :

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

Sous linux, lorsque l'on tape la commande de listage des fichiers ln -a -s dans un terminal, on passe les arguments -a et -s à une fonction main() qui a été programmée en 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

Écrire un programme qui affiche le nombre et le contenu des arguments de la fonction main() :

> ./main
1 arguments détectés
argv[0] = ./main
> ./main -f test.txt
3 arguments détectés
argv[0] = ./main
argv[1] = -f
argv[2] = test.txt

Exercice 4

Écrire une fonction qui calcule les racines d’un polynôme du second degré et qui en renvoie le discriminant :

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

Écrire un programme principal qui demande à l’utilisateur de saisir les coefficients du polynôme avant d’en afficher les racines :

Entrez le coefficient a : 2.5
Entrez le coefficient b : 4.6
Entrez le coefficient c : 18.7
 -> Racines complexes
Entrez le coefficient a : 1    
Entrez le coefficient b : 4
Entrez le coefficient c : 4
 -> Deux solutions identiques : x1 = x2 = -2.00
Entrez le coefficient a : 1.4
Entrez le coefficient b : 18.5
Entrez le coefficient c : 2
 -> Deux solutions distinctes : x1=-0.11 et x2=-13.11

Quiz

Cette function accepte quels types de passage de paramètre ?

void fct(int v);
Vérifier Bravo ! Ce n'est pas un pointer attendu dans la fonction, c'est un passage par valeur. Essaie encore ...

Cette function accepte quels types de passage de paramètre ?

void fct(int *v);
Vérifier Bravo ! Cette fois-ci c'est un pointeur qui est attendu, c'est un passage par variable aussi appelé par référence. Essaie encore ...

D'un point de vue purement syntaxique, quels types de variable peut-on passer à la fonction suivante ?

void majuscule(char *arg);
Vérifier Bravo ! Un pointeur peut pointer vers une variable ou un tableau. Essaie encore ...

Qu'affiche le code suivant ?

void addTwo(int i) { i=i+2; }
int main(void) {
  int var=5;
  addTwo(var);
  printf ("var = %d", var);
}
Vérifier Bravo ! L'argument est appelé par valeur, il ne peut pas être modifié par la fonction. Essaie encore ...

Qu'affiche le code suivant ?

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

int main(void) {
  int var=5;
  addTwo(&var);
  printf ("var = %d", var);
}
Vérifier Bravo ! Cette fois, l'argument est appelé par référence, la fonction peut modifier la valeur de la variable. Essaie encore ...

Voir aussi


Dernière mise à jour : 04/07/2023