Académique Documents
Professionnel Documents
Culture Documents
18/01/00
.premier
.premier
Case 108945
10345
.panneau
panneau contient l'adresse laquelle est stocke la variable premier, c'est donc est un pointeur vers premier.
Les pointeurs
18/01/00
/* la variable entire aaa est dclare */ /* la variable versint est dclare comme pointeur vers un entier, et contient initialement une valeur alatoire */ /* aaa est initialise la valeur 5 */ /* l'adresse de la variable aaa est mise dans versint qui est maintenant un pointeur valide */
Reprenons l'exemple ci-dessous en dtaillant l'tat de la mmoire diffrentes tapes: Etape 1: le programme est charg en mmoire et n'a pas commenc son excution Adresse case mmoire Case 0 Case 1 .. Case 078960 Contenu case mmoire peu importe ! Nom variable stocke .peu importe !
.aaa
Case 089000
Contenu de la mmoire aprs excution de la ligne aaa=5 ; Adresse case mmoire Case 0 Case 1 .. Case 078960 Contenu case mmoire peu importe ! Nom variable stocke .peu importe !
.aaa
Case 089000
Contenu de la mmoire aprs excution de la ligne versint=&aaa; Adresse case mmoire Case 0 Case 1 .. Case 078960 Contenu case mmoire peu importe ! Nom variable stocke .peu importe !
.aaar
Case 089000
078960
.versint
L'oprateur * mis devant un pointeur permet d'obtenir le contenu de la variable pointe par le pointeur; ainsi aprs excution du code prcdent, un printf("%d",*verint) afficherait 5
Les pointeurs
18/01/00
Autre exemple: main(){ int aaa,bbb; int * versint; aaa=5; versint=&aaaa; bbb=*versint;
/* les variables entire aaa et bbb sont dclares */ /* la variable versint est dclare comme pointeur vers un entier, et contient initialement une valeur alatoire */ /* aaa est initialise la valeur 5 */ /* l'adresse de la variable aaa est mise dans versint qui est maintenant un pointeur valide */ /* bbb prend pour valeur le contenu de la variable pointe par versint c.a.d la valeur contenue dans aaa */
Exemples dutilisation
1. Utilisation dans les procdures
En C, il est ncessaire de programmer de faon modulaire en utilisant des procdures,; Voici un exemple d'utilisation de procdure: void increment(int bbb) { bbb=bbb+1; printf("\n bbb vaut %d\n",bbb); return; } main(){ int aaa; /* la variable entire aaa est dclare */ aaa=5; /* aaa est initialise la valeur 5 */ increment(aaa); /* appel de incrment avec la variable aaa comme paramtre */ printf("%d",aaa); /* affichage de la valeur contenue dans aaa donc 5 */ } Droulons l'excution du programme: aaa est initialise 5 appel increment en lui "passant" aaa comme paramtre le contenu de aaa est recopi dans le variable bbb locale la procdure increment bbb est incrment de 1 on sort de la procdure increment on affiche le contenu de aaa qui vaut 5
Chaque fois que l'on appelle une procdure, les paramtres passs la procdure au moment de l'appel sont recopis dans des variables locales la procdure (on parle de passage de paramtres par valeur)
Les pointeurs
18/01/00
Pour pouvoir modifier la variable aaa depuis la procdure, il faut passer l'adresse de aaa la procdure en paramtre, adresse qui sera recopie dans une variable pointeur locale la procdure incrment; le programme devient alors: void increment(int* bbb) { /* la variable bbb est un pointeur vers un entier */ *bbb=*bbb+1; /* le contenu de la variable pointe par bbb est incrment de 1 */ printf("\n bbb pointe vers une variable entiere contenant %d\n",*bbb); return; } main(){ int aaa; /* la variable entire aaa est dclare */ aaa=5; /*la variable aaa est initialise la valeur 5 */ increment(&aaa); /* appel de incrment avec l'adresse de la variable aaa comme paramtre*/ printf("%d",aaa); /* la variable aaa contient maintenant 6 */ } Droulons l'excution du programme: aaa est initialise 5 appel increment en lui "passant" l'adresse de aaa comme paramtre (&aaa), l'adresse de aaa est recopie dans le pointeur vers entier bbb local la procdure increment, la variable dont l'adresse est contenu dans bbb est incrment de 1 (*bbb=*bbb+1) (donc le contenu de la variable aaa est incrment de 1) on sort de la procdure increment, on affiche le contenu de aaa qui vaut maintenant 6 NB: Ceci explique que lorsqu'on utilise la procdure scanf pour initialiser le contenu de variables, toutes les variables passes scanf doivent tre prcdes par & (i.e. on passe l'adresse des variables initialiser avec les valeurs saisies par l'utilisateur)
Les pointeurs
18/01/00
Il est noter que malloc retourne un pointeur vers void ; pour pouvoir mettre l'adresse retourne dans un pointeur vers un entier, il faut convertir (en anglais "cast") l'adresse retourne par malloc en pointeur vers un entier ceci est ralis dans le code ci-dessus par l'opration (int *) Pour initialiser ces 100 entiers, on pourrait modifier le programme comme ci-aprs: int * mazone,i; mazone=(int * ) malloc(100*sizeof(int)); /*allocation d'une zone de stockage pour 100 entiers */ for (i=0;i<100;i++) *(mazone+i)=i; Dans le code ci-dessus mazone contient l'adresse du 1er entier , mazone+1 pointe sur le deuxime entier, mazone+n sur l'entier n-1(n<100). Attention: il ne faut jamais perdre l'adresse du dbut de la zone alloue par malloc sous peine de ne plus pouvoir y accder; vous trouverez ci dessous un exemple dnerie!!! En effet dans l'exemple ci-dessous, on s'alloue une zone de mmoire, et aprs on modifie le pointeur sens y donner accs en y mettant une autre adresse:
/* mazone contient l'adresse du dbut d'un bloc suffisant pour stocker 100 entiers */ /* mazone contient maintenant l'adresse de a on ne sait plus o commence la zone de 100 entiers */
Il est noter qu'une faon plus srieuse de coder consisterait tester le code de retour de mallocEn effet, si le systme ne peut vous allouer de la mmoire (memoire sature par exemple), le pointeur retourn vaut NULL et est donc inutilisable par exemple:
int * mazone; mazone=(int * ) malloc(100*sizeof(int)); if(mazone==(int *)NULL) { /* si mazone vaut NULL , le malloc n'a pas march le systme a refus d'allouer la zone de 100 entiers */ printf("\nallocation mmoire refuse\n"); exit(-1); };
Les pointeurs
18/01/00
Pour dpanner il suffit au choix : De regarder attentivement son code (ventuellement rajout de printf pour savoir o on en est au moment du "core dump") Ou bien De compiler avec l'option de debuggage (-g), de rexcuter votre programme pour rgnrer un fichier core; puis de lancer le debuggeur; Avec xxgdb utiliser la commande bt (a donnera la ligne o le programme s'est plant) Avec ddd utiliser le menu status->backtrace