{{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