IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa LES POINTEURS 2 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Gnralits Une variable de type pointeur est une variable dont la valeur est l'adresse d'un objet. Dfinition de variable de type pointeur : <nom_de_type> *<nom_de_variable> ; Exemple : char *pc ; // pc est une variable de type pointeur de char int *pi ; // pi est une variable de type pointeur de int short *ps ; // ps est une variable de type pointeur de short La valeur de la variable pc (aprs affectation) est l'adresse d'un objet de type char. MurielleTORREGROSSA Architecture des ordinateurs 2 3 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Oprateurs adresse & et contenu * Syntaxe : &<nom_de_variable> La valeur de cette expression est l'adresse de la variable. Le type de cette expression est : pointeur de <type de la variable > . Syntaxe: *<expression_de_type_pointeur> La valeur de cette expression est le contenu de la zone mmoire adresse par l'<expression de type pointeur>. 4 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Oprateur adresse & Exemple : char c , *pc ; pc = &c ; // l'adresse de la var. c est stocke dans pc Attention , les critures suivantes sont fausses: &(x+3) &3 Exemple : int x = 5 , y , *pi ; pi = &x ; //pi aura pour valeur l'adresse de la variable x pi x 5 MurielleTORREGROSSA Architecture des ordinateurs 3 5 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Oprateur contenu * Exemples : int x = 5 , y , *pi ; pi = &x ; /*pi aura pour valeur l'adresse de la var. x */ y = *pi + 1 ; /* la variable y aura pour valeur 6 */ *pi = 4 ; /* la variable x aura pour valeur 4 */ *pi = *pi +1; /* la variable x aura pour valeur 5 */ (*pi)++; /* la variable x aura pour valeur 6 */ 6 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Oprateur contenu * Remarques : Si p est une variable de type pointeur, les expressions p et *p sont des " lvalue" . Les variables p et *p peuvent tre places gauche de l'oprateur d'affectation. La dfinition int *pi ; ne rserve pas un emplacement pour un entier. La valeur de la variable pi est indtermine aprs sa dfinition. MurielleTORREGROSSA Architecture des ordinateurs 4 7 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Pointeurs et fonctions Nous avons vu que, lorsque les paramtres formels correspondent des variables scalaires, l'appel se fait par valeur (pas de modification des paramtres d'appel par la fonction) . 8 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Pointeurs et fonctions Exemple : main( ) { int a =3 , b =5 ; // a b swap (a , b) ; // appel par valeur } void swap ( int x , int y ) { int z ; // x y z =x ; // puis modification x =y ; // uniquement des paramtres y =z ; // formels } 3 5 3 5 MurielleTORREGROSSA Architecture des ordinateurs 5 9 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Pointeurs et fonctions Pour que la fonction puisse modifier le contenu des variables d'appel , on utilisera des paramtres formels de type pointeur. Il y a toujours appel par valeur , mais la valeur du paramtre d'appel (&a) est une adresse (pointeur de int). Cette adresse est recopie dans la zone correspondante du paramtre formel px , qui est lui aussi de type pointeur de int. 10 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Pointeurs et fonctions Exemple : main() { int a = 3 , b = 5 ; // a b swap (&a , &b) ; } void swap (int *px , int *py) { int z ; // px py z = *px ; *px = *py ; *py = z ; } 3 5 &a &b MurielleTORREGROSSA Architecture des ordinateurs 6 11 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Pointeurs et noms de tableaux La dfinition: short a[10] ; correspond la rservation de 10 emplacements mmoire conscutifs dsigns respectivement par : a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] Considrons les instructions suivantes : short *pa ; // pa est une var. de type pointeur de short pa = &a[0] ; // stocke dans pa l'adresse du 1er lment // du tableau a pa = &a[i] ; // stocke dans pa l'adresse de l'lment // d'indice i du tableau a 12 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Pointeurs et noms de tableaux Dfinition : Si la variable pa de type pointeur de short contient l'adresse d'un lment particulier a[i] du tableau de short a , alors: pa+1 "pointe" sur l'lment a[i+1] cd l'lment suivant pa-1 "pointe" sur l'lment a[i-1] cd l'lment prcdent pa+k "pointe" sur l'lment a[i+k] (le kme lment aprs a[i] ). MurielleTORREGROSSA Architecture des ordinateurs 7 13 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Les oprateurs + et - Les oprateurs + ou - , avec comme oprandes un pointeur et un entier, ne sont pas les oprateurs + ou - ordinaires. Les oprateurs + ou - dpendent du type de l'objet point. D'aprs la dfinition prc., si pa = &a[i] ; alors: *pa dsigne le contenu de a[i] *(pa+1) dsigne le contenu de a[i+1] *(pa+k) dsigne le contenu de a[i+k] Il y a une correspondance trs troite entre la notation indice et l'arithmtique des pointeurs. 14 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Les oprateurs + et - Dfinition : Le nom d'un tableau est une constante de type pointeur de type gal au type des lments du tableau. Cette constante a pour valeur l'adresse du premier lment du tableau. Ce n'est pas une lvalue. MurielleTORREGROSSA Architecture des ordinateurs 8 15 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Les oprateurs + et - Exemple : int t[20] ; // t est une constante de type pointeur de int // gale l'adresse de t[0]. Par consquent : l'expression t a pour valeur l'adresse de l'lment t[0] l'expression t+1 a pour valeur l'adresse de l'lment t[1] l'expression t+i a pour valeur l'adresse de l'lment t[i] donc : t + i <=> &t[i] *(t + i) <=> t[i] 16 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Remarque 1 La mme quivalence est valable pour les variables de type pointeur. Exemple : Soit : char a[20] , *pa ; pa = a ; alors : *(pa+i) <=> pa[i] MurielleTORREGROSSA Architecture des ordinateurs 9 17 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Remarque 2 Considrons les dfinitions char *pa , a[30] ; pa est une variable, donc: pa = a ; // Correct !! pa++ ; // Correct !! le nom de tableau a est une constante (a dsigne toujours l'adresse de l'lment a[0]), donc: a = pa ; // Faux !! a++ ; // Faux !! 18 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Remarque 3 Quand un nom de tableau est fourni comme paramtre d'appel une fonction, c'est la valeur de ce nom (c'est dire l'adresse du 1 er lment du tableau) qui est transmise et stocke dans la zone correspondant au paramtre formel (qui doit tre de type pointeur). La transmission des paramtres est toujours une transmission par valeur. MurielleTORREGROSSA Architecture des ordinateurs 10 19 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Exemple : Rcriture de la fonction strlen int strlen ( char *s ) { int i = 0 ; while ( *(s+i) != '\0') i++ ; return i; s } main() { char a[12] ; a I | U | T | \0 | .. | int n ; printf (" introduire la chaine : " ) ; scanf (" %s" , a) ; n = strlen(a) ; printf (" longueur de la chaine : %d\n" , n) ; } 20 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Exemple : Rcriture de la fonction strlen En appliquant l'quivalence entre notation pointeur et notation indice *(pa+i) <=> pa[i] , la fonction strlen peut encore s'crire : int strlen ( char *s ) { int i = 0 ; while( s[i] != '\0') i++ ; return i ; } MurielleTORREGROSSA Architecture des ordinateurs 11 21 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Exemple : Rcriture de la fonction strlen Pour se rapprocher d'avantage de la notation indice, le langage C permet de remplacer la dfinition du paramtre formel : int strlen ( char *s ) par l'criture quivalente suivante : int strlen ( char s[ ] ) 22 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Exemple : Rcriture de la fonction strlen La fonction strlen s'crit alors: int strlen ( char s[ ] ) { int i = 0 ; while ( s[i] != '\0 ) i++ ; return i ; } MurielleTORREGROSSA Architecture des ordinateurs 12 23 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Exemple : Rcriture de la fonction strcpy strcpy copie la chane de caractres stocke dans le tableau t dans le tableau s void strcpy ( char *s, char *t) { while ( ( *s = *t ) != '\0') { s++ ; t++ ; } } 24 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Exemple : Rcriture de la fonction strcpy Ce qui peut encore s'crire : void strcpy ( char *s, char *t) { while ( ( *s++ = *t++ ) != '\0') ; } ou encore: void strcpy ( char *s, char *t) { while ( *s++ = *t++ ) ; } MurielleTORREGROSSA Architecture des ordinateurs 13 25 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Constantes chane de caractres et pointeurs L'criture dans un source C d'une constante chane de caractres ( par exemple " abcd" ) correspond une constante de type pointeur de char non explicite dont la valeur est gale l'adresse du premier lment d'un tableau de char contenant la chane de caractres. 26 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Constantes chane de caractres et pointeurs Exemple 1 : La constante " abcd" est transforme par le compilateur en : a b c d \0 (constante de type pointeur de char non explicite) MurielleTORREGROSSA Architecture des ordinateurs 14 27 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Constantes chane de caractres et pointeurs Exemple 2 : Soit : char s[20] , *t ; l'instruction t = " abcd" ; est correcte l'instruction s = " abcd" ; est fausse l'instruction strcpy ( s , " abcd" ) ; est correcte l'instruction strcpy ( t , " abcd" ) ; est correcte condition que la valeur de la variable t soit gale l'adresse d'un tableau d'au moins 5 char. 28 IUTR. SchumanStrasbourg R. Stutzman, M. Torregrossa Remarque Le seul cas o une constante chane de caractres n'est pas considre par le compilateur comme un pointeur constant de type char est celui de l'initialisation d'un tableau de char lors de sa dfinition. Au lieu d'crire par exemple : char a[10] = {'I' , 'U', 'T', '\0 }; on peut crire de manire quivalente char a[10] = " IUT" ; Dans ce seul cas, " IUT" est considre comme une numration de caractres {'I', 'U', 'T', '\0'}.