Outils pour utilisateurs

Outils du site


dev:c-cpp:pointeurs

pointeurs et tableaux

Un pointeur est une variable dont la taille est adaptée au stockage de l'adresse d'une autre variable. On déclare un pointeur via l'opérateur * suffixé par le type pointé.

// Déclaration d'une variable de type pointeur sur entier ayant le label ptr_int
int* ptr_int;

Lors de la déclaration de la variable, un espace mémoire est attribué mais son contenu est aléatoire car non initialisé. Il faut donc le définir avant toute utilisation:

  • Par affectation de la valeur NULL,
  • Par affectation de l'adresse d'une autre variable,
  • Par allocation dynamique.
ptr_int = NULL;
ptr_int = &entier_a;
ptr_int = malloc( sizeof(int));

Une difficulté à l'usage des pointeurs c'est que le même symbole, l'astérisque est utilisé pour:

  • Déclarer le type pointeur
  • Accéder à la valeur pointée (opérateur de déréférence)
int a=12;
 
//Déclaration de ptr_int, un pointeur sur un entier. Ici affectation de l'adresse mémoire de la variable a 
int* ptr_int = &a;
 
//on incrémente la valeur de la variable dont l'adresse est stockée dans ptr_int (on dit pointée par ptr_int). Ce n'est pas ptr_int qui est incrémenté.
*ptr_int++;

Le tableau

Le tableau est une suite contiguë d'éléments de même type. En C une chaine de caractères est un tableau de caractères (tableau d'éléments de type char).

// Les délcaration/affectations suivantes sont équivalentes:
// dans tous les cas, chaine_* est un tableau de 8 caractères.
 
char chaine_a[8] = {'e','x','e','m','p','l','e','\0'};
char chaine_b[] =  {'e','x','e','m','p','l','e','\0'};
char chaine_c[] =  "exemple";
char* chaine_d =   "exemple";

Là encore il faut être vigilant et ne pas confondre déclarations et affectations:

//Déclaration d'une variable nommée tab de type tableau de 10 éléments entiers initialisés à 0;
int tab[10]={0};
 
//Affectation de la valeur 0 au 11ième élément du tableau tab
tab[10]=0;

Passer un tableau en argument à une fonction

En C, la déclaration d'une fonction utilise les paramètres formels. Pour le cas d'une fonction prenant en paramètre un tableau ces différentes notations sont équivalentes:

void fonction_a(int tab[10]);
void fonction_b(int tab[]);
void fonction_c(int* tab);

Passer un tableau à une fonction c'est nécessairement faire un passage par adresse.

void ma_fonction( int* ptab)

Retourner un tableau

Toute variable déclarée sans le mot clé static a une portée locale. Le compilateur refusera de retourner une variable locale. On peut retourner un pointeur mais attention s'il pointe sur une variable locale cela aboutira certainement à un bogue car elle sera dans un état aléatoire lorsque elle sera utilisée par la fonction appelante.

int* fonction_boguee(void)
{
   // declaration d'une variable locale, un tableau de 4 entiers
   int tab[] = {1,2,3,4};
 
   // pas d'erreur syntaxique mais retourne l'adresse d'une variable locale dont l'état
   // est aléatoire dès que la fonction se termine 
   return tab;
}

Dans une fonction il faut donc allouer dynamiquement et retourner un pointeur.

Références

dev/c-cpp/pointeurs.txt · Dernière modification : 2021/02/01 21:51 de 127.0.0.1