Académique Documents
Professionnel Documents
Culture Documents
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
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
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.
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
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) ;
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 :
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]
…..
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 ?
26