Vous êtes sur la page 1sur 26

Cours 

de Langage C
Cours de Langage C
Pointeurs et tableaux
Pointeurs et tableaux
R
Rappel : codage binaire ‐
l d bi i h d i l
hexadecimal

 En base 10 : on exprime les nombres avec 10 chiffres de 0 à 9 
 1984 = 1.10
1984 = 1 10^33 + 9.10
+ 9 10^2
2 + 8.10
+ 8 10^1
1 + 4.10
+ 4 10^0

 En base 2 : on a seulement 2 chiffres 0 et 1
 1011= 1.2^3 + 0.2^2 + 1.2^1 + 1.2^0 
 soit 11 en décimal

 En base 16 ou en hexadécimal : on exprime les nombres avec 10 chiffres 
de 0 à 9 et 5 lettres de A à E 
 10AF = 1.16^3 + 0.16^2 + 10.16^1 + 15.16^0 soit 4271 en décimal

2
R
Rappel : Stockage des variables
l St k d i bl
Type en C Nom Français Taille (octets) Valeurs permises
unsigned short int entier court non signé 2 0 à 65 536
short entier court 2 -32 768 à 32 767
unsigned long int entier long non signé 4 0 à 4 294 967 295
long int entier long 4 -2 147 483 648 à 2 147 483 647
int entier (16 bits) 2 -32 768 à 32 767
int entier (32 bits) 4 -2 147 483 648 à 2 147 483 647
g
unsigned int entier non signé
g ((16 2
0 à 65 536
bits)
unsigned int entier non signé (32 4
0 à 4 294 967 295
bits)
char texte 1 2 6 caractères
256 è (0 à 255)
2 )
float nombre décimal 4 1.2e-38 à 3.4e38
double nombre double 8 de 2.2e-308
2.2e 308 à 1.8e308

3
St k
Stockage et adresse
t d
 Dans la mémoire de l
Dans la mémoire de l’ordinateur
ordinateur, les données sont stockées 
les données sont stockées
sous forme binaire.
 La mémoire est divisée en « cases » de taille 8 bits, appelées 
La mémoire est divisée en « » de taille 8 bits appelées
octets (bytes en anglais). 
 Chaque octet est repéré par son adresse, qui est souvent  
q p p ,q
donnée par un nombre hexadécimal. 
1 octet 1 octet

1 bit (0 ou 1)

B01C B01D

Adresse de l’octet Adresse de l’octet suivant
4
I t d ti
Introduction aux pointeurs
i t
int x ;
 Cette « déclaration de  variable » réalise deux opérations : 
 Défi i i d’
Définition d’une variable x pouvant être utilisée dans le 
i bl ê ili é d l
programme pour manipuler des données. 
 Réservation ou allocation d’un espace mémoire où sera
Réservation ou allocation d’un espace mémoire où sera 
stocké le contenu de la variable.  
 La variable x est stockée sur 4 octets Son adresse est celle du
La variable x est stockée sur 4 octets. Son adresse est celle du 
1er octet, soit ici B01C.
x

B01C B01D B01E B01F B020 B021 Adresses des octets

5
L
Les pointeurs
i t
int x ;
 La variable x a une adresse en mémoire. 
 D
Dans l’exemple précédent c’est B01C.
l’ l é éd t ’ t B01C
 Pour avoir accès à l’adresse de la variable x, on utilise 
ll’opérateur
opérateur &.
&
 &x représente l’adresse de la variable x.
 Pour manipuler les adresses on définit un nouveau type de
Pour manipuler les adresses on définit un nouveau type de 
variable : les pointeurs.

Un pointeur est une variable qui 
contient l’adresse
contient l adresse dd’une
une autre 
autre
variable.  C’est une adresse typée. 
6
L
Les pointeurs
i t
 Déclaration d’un pointeur :  double *p ;
 p est un « p
pointeur sur une variable de type double
yp ».
 p est une adresse typée.
 C’est l’adresse de la première case mémoire contenant la donnée. On 
dit
dit que p pointe sur une variable.
i t i bl

 Utilisation = Accès à la variable pointée par p : 
Utilisation  Accès à la variable pointée par p : on utilise  
on utilise *
 *p représente le contenu de la variable pointée par p

 Initialisation d’un
Initialisation d un pointeur : 
pointeur :
 On peut donner l’adresse d’une variable déjà existante : 
double y ;
double *p ;
p=&y ; 7
L
Les pointeurs
i t
 Pointer sur la case suivante :
 p+1 pointe sur le double suivant en mémoire.
 Contenu de la case mémoire suivante : 
 *(p+1)est le contenu de la variable pointée par p+1.

double y ; La variable y est stockée sur 8 octets. 


double *p ; L’adresse de y est F01A. p
y p vaut donc F01A.
p p=&y ;
y
p+1

F01A F01B F01C … F021

8
V i bl
Variables et pointeurs
t i t
double x ; double *p ;
&x existe à la déclaration p
p n’existe pas encore à la déclaration
p
En mémoire, il ne s’est rien passé
x = 5 ; *p p = 5 ;
OK Pas d’erreur à la compilation 
((warning), mais plantage à 
g), p g
l’exécution
double x ;
p=&x ;
, p
OK, initialisation correcte de p
*p = 5 ;
9
E
Exemples
l
int n;
int *p;
n=5;
;
printf(«%d\n »,n); 5
*p désigne le contenu de 
la case mémoire pointée 
p=&n;
par p
printf(«%d\n »,*p); 5
*p=1;
%x est le format pour les 
printf(«%d\n »,n); 1 adresses en hexadécimal
printf(«%d\n
( \ »,*p);
) 1

printf(«%x %x\n »,p,&n); BC01 BC01

printf(«%x %x\n »,p+1,&n+2 ); BC05 BC09


10
R t
Retour sur les fonctions
l f ti
En C, une fonction travaille sur des copies des variables.
En C une fonction travaille sur des copies des variables
On parle de « passage d’argument par valeur »
void ma_fonction(int
( a)
)
{
a = 0 ;
}
main( )
{
int b = 5 ;

printf(« %d »,b) ; Affiche 5

ma_fonction(b) ;
Affiche 5 : ma_fonction
ma fonction n’a pas
printf(« %d »,b) ;
modifié la variable b définie dans
} 11
le main … Pourquoi ?
R t
Retour sur les fonctions
l f ti
En C, une fonction travaille sur des copies des variables.
En C une fonction travaille sur des copies des variables
On parle de « passage d’argument par valeur »
void ma_fonction(int
( a)
) 2-Création a
{ d’une variable a 5
a = 0 ; à l’adresse ad1 ad1
} b
main( ) 5
{ ad2
int b = 5 ; 1-Création et initialisation à 5
d’une variable b à l’adresse ad2
printf(« %d »,b) ;

ma_fonction(b) ; 3-Recopie de la variable b dans la


variable a (donc a vaut 5)
printf(« %d »,b) ;
} 12
R t
Retour sur les fonctions
l f ti
En C, une fonction travaille sur des copies des variables.
En C une fonction travaille sur des copies des variables
On parle de « passage d’argument par valeur »
void ma_fonction(int
( a)
) 2-Création a
{ d’une variable a 0
a = 0 ; 4-a vaut 0 à l’adresse ad1 ad1
} b
main( ) 5
{ ad2
int b =5 ; 1-Création et initialisation à 5
d’une variable b à l’adresse ad2
printf(« %d »,b) ;

ma_fonction(b) ; 3-Recopie de la variable b dans la


variable a (donc a vaut 5)
printf(« %d »,b) ; 5-Il ne s’est rien passé à l’adresse de la
} variable b qui n’est donc pas modifiée 13 !
P
Passage d’arguments par adresse
d’ t d
Un des intérêts des pointeurs : modifier la valeur de variables 
p
dont l’adresse est passée comme argument d’une fonction.

Exemple : échanger 2 variables (exercice 1 du TD)


Exemple : échanger 2 variables (exercice 1 du TD)
#include<stdio.h>
void echange(int x,int y)
{
int temp; Idée intuitive , 
temp=y;
p y;
y=x;
mais qui ne
mais qui ne 
x=temp; marche pas !
}
main()
{
int a=3,b=258;
echange(a,b);
printf("%d\t%d\n",a,b);
14
}
P
Passage d’arguments par adresse
d’ t d
Un des intérêts des pointeurs : modifier la valeur de variables 
p
dont l’adresse est passée comme argument d’une fonction.

Exemple : échanger 2 variables (exercice 1 du TD)


Exemple : échanger 2 variables (exercice 1 du TD)
#include<stdio.h> x y
void echange(int x,int y) 2-Création
2 Création deux 3 258
{ variables x et y
int temp; &x &y
3-Recopie de a
temp=y;
p y;
et b dans x et y
y=x;
x=temp;
}
main()
{ a b
int a=3,b=258; 1-Création et initialisation de 3 258
echange(a,b); deux variables a et b &a &b
printf("%d\t%d\n",a,b);
15
}
P
Passage d’arguments par adresse
d’ t d
Un des intérêts des pointeurs : modifier la valeur de variables 
p
dont l’adresse est passée comme argument d’une fonction.

Exemple : échanger 2 variables (exercice 1 du TD)


Exemple : échanger 2 variables (exercice 1 du TD)
#include<stdio.h> x y
void echange(int x,int y) 2-Création deux 258 3
{ variables x et y
int temp; &x &y
3-Recopie de a
temp=y; et b dans x et y
y=x;
x=temp; 4-Echange des
} valeurs de x et y
main()
{ a b
int a=3,b=258; 1-Création et initialisation de 3 258
echange(a,b);
h ( b) deux variables a et b &
&a &b
printf("%d\t%d\n",a,b);
}  a et b n’ont pas été modifiées ! 16
P
Passage d’arguments par adresse
d’ t d
Un des intérêts des pointeurs : modifier la valeur de variables 
p
dont l’adresse est passée comme argument d’une fonction.

Exemple : échanger 2 variables (exo 1 du TD 5)


Exemple : échanger 2 variables (exo 1 du TD 5)
#include<stdio.h>
void echange(int *x,int *y)
{
int temp;
temp=*y;
*y=*x; Bonne méthode !
Bonne méthode !
*x=temp;
}
main()
{
int a=3,b=258;
(& &b)
echange(&a,&b);
h
printf("%d\t%d\n",a,b);
} 17
P
Passage d’arguments par adresse
d’ t d
Un des intérêts des pointeurs : modifier la valeur de variables 
p
dont l’adresse est passée comme argument d’une fonction.

Exemple : échanger 2 variables (exo 1 du TD 5)


Exemple : échanger 2 variables (exo 1 du TD 5)
#include<stdio.h>
void echange(int *x,int *y) 2-Création de deux p pointeurs
{ x et y initialisés à &a et &b :
int temp; « x pointe sur a » et « y
temp=*y; pointe sur b »
*y=*x; a b
*x=temp; 3- L’échange se fait bien à 3 258
} &a et &b &a &b
main()
{ x y
int a=3,b=258; 1-Création et initialisation de
(& &b)
echange(&a,&b);
h deux variables a et b
printf("%d\t%d\n",a,b);  a et b ont bien été modifiées !
} 18
E
Exemple : la fonction triple
l l f ti t i l
 Le code : • Le code :
a = 3*a ; a = 3*a ; b = 3*b ; c=3*c ;
est codé dans une 
t dé d est codé dans une fonction 
dé d f i
fonction triple(a) triple(a,b,c)
Le code est :
Le code est : Le code est :
Le code est :
int triple(int a) int triple(int a,int b,int c)
{ {
a = 3*a ; a = 3*a ; b = 3*b ; c=3*c ;
return (a) ; return (a) ;
} }
Et l’appel a=triple(a) Et l’appel : a=triple(a,b,c)

modifie bien a !  modifie a mais ne modifie ni b, ni c ! 
E
Exemple : la fonction triple
l l f ti t i l
• Le nouveau code pour modifier a, b et c simultanément est :

void triple(int *a, int *b, int *c)


{
* = 3*(*
*a 3*(*a)
) ; *b = 3*(*b) ; *c=3*(*c);
* 3*(* )
}

Et l’appel  : 

triple(&a,&b,&c) modifie bien les variables a, b et c

Conclusion :  une fonction peut modifier plusieurs variables 
f f
grâce aux pointeurs
T bl
Tableaux et pointeurs
t i t
i
int tab[100];
b[100]
 Cette déclaration fait deux choses :
 Définition d’une variable pouvant être utilisée dans le 
Définition d’ ne ariable po ant être tilisée dans le
programme pour manipuler des données.
 Allocation d
Allocation d’un
un espace mémoire de 100 cases contigües de 
espace mémoire de 100 cases contigües de
4 octets.  

 En fait, un tableau n’est rien d’autre qu’un pointeur !

 La variable tab est un pointeur
La variable tab est un pointeur qui est l’adresse du 1er élément 
qui est l’adresse du 1er élément
du tableau. En d’autres termes, le nom d’un tableau est l’adresse 
de son 1er élément.
de son 1er élément.
T bl
Tableaux et pointeurs
t i t
i
int tab[100];
b[100]
tab est l’adresse de tab[0]

tab+i est l’adresse de tab[i]

Il y a équivalence entre tab+i et &tab[i]


et entre *(tab+i)
( ) et tab[i]
[ ]
tab tab+1 tab+2
tab[0] tab[1] tab[2]

…..
D01A … … D01E D021
22
E
Exemple
l

int tab[100];

for(i=0;i<n;i++) tab[i]=i;


printf(«%d\n
i tf( %d\ »,tab[0]);
t b[0])
 Affiche les 
printf(«%d\n »,*tab); même valeurs !
printf(«%d %d\n »,*(tab+1),tab[1]);  Même valeur !
printf(«%x %x\n»,tab,&tab[0];  Affiche la même adresse !

23
Tableaux et pointeurs dans les 
p
fonctions
Il y a équivalence entre :
void initialise
initialise_tableau(int
tableau(int tab[ ]
], int dim);

main()
{
int T[100] ;
initialise_tableau(T,100)
_ ;
}

void initialise_tableau(int
( tab[
[ ], int dim)
)
{
int i ;
for (i=0 ; i<dim ; i++) tab[i]=0;
}
24
Tableaux et pointeurs dans les 
p
fonctions
et :
void initialise
initialise_tableau(int
tableau(int *tab
tab, int dim);

main()
{
int T[100] ;
initialise_tableau(T,100)
_ ;
}

void initialise_tableau(int
( *tab,
, int dim)
)
{
int i ;
for (i=0 ; i<dim ; i++) tab[i]=0;
}
25
En résumé : Pour bien concevoir une 
fonction utilisant les pointeurs
 Déterminer ce que doit retourner la fonction :
 Souvent void (la fonction a déjà modifié les valeurs)
 Parfois un type standard (int, double, …)
 Certaines fonctions retournent des adresses
donc de type pointeur sur qqe
yp p qq chose : int* ,, double*, ...
,

 Typer la fonction en conséquence 

 Identifier ce qu’on passe à la fonction :
 fonction(int a, double b)
 Des valeurs ?  

 Des adresses ?  fonction(int *a, double *b)

26

Vous aimerez peut-être aussi