====== Pointeurs ====== ===== Variable ordinaire ===== Supposons que je définisse un entier : int x = 12; La déclaration ''%%int x%%'' réserve en mémoire un espace de deux octets destinés à contenir un entier. On écrit aussitôt 12 en codage CA2, donc ''%%0000 0000 0000 1100%%'' dans ces deux octets. Dans la suite du programme, on pourra rencontrer des lignes comme y = x + 3; x = 5; x = x + 1; * ligne 1 : c'est la valeur contenue dans la case mémoire étiquetée x qui intervient dans le calcule. Donc ici ce serait 12. * ligne 2 : on écrit la valeur 5 dans la case mémoire étiquetée par x * linge 3 : les deux cas précédents l'un après l'autre. On commence par lire le contenu de la mémoire étiquetée par x, on trouve 5, on fait le calcul qui donne 6 et on écrit le résultat dans la mémoire étiquetée par x. À chaque fois, x désigne le contenu d'une certaine mémoire contenant un entier. ===== Adresse ===== #include #include int main() { int x = 12; printf("%u\n", &x); return 0; } ligne 6, on affiche ''%%&x%%'' c'est à dire l'adresse de la mémoire ''%%x%%''. Le formatage demandé est ''%%"%u\n"%%'', c'est l'affichage d'un entier non signé (binaire naturel, pas de CA2, ce qui est logique étant donné que l'adresse ne devrait pas être négative !) Donc le caractère ''%%&%%'' sert à obtenir l'adresse d'une variable (déjà été signalé dans l'appel de fonction ''%%scanf%%'' lors de l'exemple de l'[[.:inputs|imc]].) ===== Pointeur ===== Un pointeur est une variable dont le contenu est une adresse vers un contenu en mémoire. #include #include int main() { int x = 13; int *p; p = &x; printf("%u\n", p); printf("%d\n", *p); return 0; } * Ligne 5 on définit la variable ''%%x%%'' contenant 13. * Ligne 6 on définit un pointeur ''%%p%%'' qui devra pointer une case mémoire contenant un entier. Comprendre que ''%%p%%'' contiendra l'adresse mémoire d'une mémoire contenant un ''%%int%%''. * Ligne 7, on affecte à ''%%p%%'' l'adresse de ''%%x%%'' si bien que le pointeur ''%%p%%'' pointe maintenant sur la case mémoire ''%%x%%''. * Ligne 8, le contenu de ''%%p%%'' est donc l'adresse. * Ligne 9, en écrivant ''%%*p%%'' on désigne le contenu de la case mémoire pointée, donc ici le contenu de ''%%x%%''. En quelque sorte, ''%%*%%'' fait le contraire de ''%%&%%''. **Remarque :** On peut écrire ''%%int* p%%'' qui est équivalent à ''%%int *p%%''. === Ce qu'on ne pourrait pas faire... === int *p = 17; Ne fonctionnera pas. En effet, en définissant ''%%int *p%%'' on définit la variable ''%%p%%'' pointant sur un entier, mais on n'a pas définit sur quel entier ''%%p%%'' doit pointer. Pour l'instant ''%%p%%'' ne pointe nulle part et on n'a donc aucun endroit où écrire ''%%17%%''. int x = 17; int *p; *p = 17; Ne fonctionnera pas non plus, pour la même raison. === Mais ceci fonctionne... === int x = 17; int *p = &x; *p = 25; Cette fois on initialise ''%%p%%'' en lui donnant une adresse ''%%&x%%'' ce qui revient à dire que ''%%p%%'' pointera sur ''%%x%%''. Prenons l'exemple plus complet : #include #include int main() { int x = 17; int *p = &x; *p = 25; printf("%d\n", x); return 0; } En ligne 7, on modifie le contenu de la case pointée par ''%%p%%'', c'est à dire que l'on modifie ''%%x%%'' ce que l'on voit ligne 8 lors de l'affichage de ''%%x%%''. Autrement dit, dès lors que ''%%p = &x%%'', ''%%*p%%'' devient équivalent à ''%%x%%''.