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:
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:
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 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;
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)
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.