{{tag>dev c pointeurs tableaux}}
====== 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 =====
* https://openclassrooms.com/courses/tableaux-pointeurs-et-allocation-dynamique