Apprendre le Langage C

Pointeur

Introduction :

En C, les pointeurs jouent un rôle primordial dans la définition de fonctions: Comme le passage des paramètres en C se fait toujours par la valeur, les pointeurs sont le seul moyen de changer le contenu de variables déclarées dans d'autres fonctions. Ainsi le traitement de tableaux et de chaînes de caractères dans des fonctions serait impossible sans l'utilisation de pointeurs.

En outre, les pointeurs nous permettent d'écrire des programmes plus compacts et plus efficients et fournissent souvent la seule solution raisonnable à un problème. Ainsi, la majorité des applications écrites en C profitent extensivement des pointeurs.

Appel par référence :

Toutes les variables en C, à l'exception des tableaux, sont passés par valeurs aux paramètres des fonctions. C'est à dire qu'une copie est effectuée sur la pile d'appel. Si bien que toutes les modifications de la variable effectuées dans la fonction seront perdues une fois de retour à l'appelant. Or, il y a des cas où l'on aimerait bien pouvoir modifier une variable passée en paramètre et que ces modifications perdurent dans la fonction appelante. C'est un des usages des paramètres par adresse : permettre la modification d'une variable de l'appelant.

Pour changer la valeur d'une variable de la fonction appelante,
nous allons procéder comme suit:
- la fonction appelante doit fournir l'adresse de la variable et
- la fonction appelée doit déclarer le paramètre comme pointeur.
On peut alors atteindre la variable à l'aide du pointeur.

Exemple :

Nous voulons écrire une procédure permute qui échange le contenu de deux variables de type int. En première approche, nous écrivons la proédure suivante:

void permute(int A, int B)
{
	int temp;
	temp = A;
	A = B;
	B = temp;
}
			

Nous appelons la procédure pour deux variables X et Y par:

	permute(X,Y)

Résultat: X et Y restent inchangés !

Explication: Lors de l'appel, les valeurs de X et de Y sont copiées dans les paramètres A et B. permute échange bien contenu des variables locales A et B, mais les valeurs de X et Y restent les mêmes.

Pour pouvoir modifier le contenu de X et de Y, la procédure permute a besoin des adresses de X et Y. En utilisant des pointeurs, nous écrivons une deuxième procédure:

void permute (int *A, int *B)
{
	int temp;
	temp = A;
	A = B;
	B = temp;
}
			

Nous appelons la procédure par:

	permute(&X,&Y);

Résultat: Le contenu des variables X et Y est échangé !

Explication: Lors de l'appel, les adresses de X et de Y sont copiées dans les pointeurs A et B. permute échange ensuite le contenu des adresses indiquées par les pointeurs A et B.

Maintenant voici le code complet du programme :

#include <stdio.h>
/* Ce code échange le contenu de deux variables */
void permute(int *A, int *B)
{
	int temp;
	temp = *A;
	*A = *B;
	*B = temp;
}
int main(void)
{
	int X = 5;
	int Y = 2;
	printf("X = %d, Y = %d.\n", X, Y);
	/* On passe à 'permute' les adresses de X et Y. */
	permute(&X, &Y);
	printf("X = %d, Y = %d.\n", X, Y);
	permute(&X, &Y);  //retour au l'état du début
	printf("X = %d, Y = %d.\n", X, Y);
	return 0;
}
			

À noter :

Ce passage par adresse est extrêmement répandu pour optimiser la quantité de données qui doit transiter sur la pile d'appel (qui est, sur beaucoup de systèmes, de taille fixe). En fait, même si la variable ne doit pas être modifiée, on utilise quand même un passage par adresse, juste pour éviter la copie implicite des variables autres que les tableaux. Ceci est particulièrement intéressant avec les structures, puisque celles-ci ont tendance à être assez imposantes, et cela ne nuit pas trop la lisibilité du programme.