Allocation de tableaux D´eclaration de nouveaux types
I3 – Algorithmique et programmation Introduction ` a la programmation en langage C
Cours n
◦5
Gestion de la m´ emoire en C Structures de donn´ ees et types d´ eriv´ es
Camille Coti
camille.coti@iutv.univ-paris13.fr
IUT de Villetaneuse, d´epartement R&T
2011 – 2012
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
1
Allocation de tableaux Allocation statique Allocation dynamique Utilisation
2
D´ eclaration de nouveaux types Structure
Enum´ ´ eration
Remarque : taille
Type d´ eriv´ e
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Tableaux
Rappel : Tableaux
Un tableau est un type particulier de variable. Il contient un ensemble de variables de mˆ eme type, stock´ ees de fa¸ con contigu¨ e en m´ emoire.
Exemple : tableau d’entiers 3 5 2 1 12 5 2 9
Parcours d’un tableau : d´ ebut
1
monT ableau[10] : T ableau d
0Entiers
2
pour i ←− 0 ` a 9 pas 1 faire
3
monT ableau[i] ←− 2 ∗ i
4
finpour
5
fin
6
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
D´ eclaration d’un tableau
En C :
D´ eclaration d’un tableau Type des donn´ ees contenues Taille fixe
On ne peut pas d´ epasser les limites du tableau (SEGFAULT)
On peut parcourir le tableau avec une boucle for (par exemple) :
1 i n t i ;
2 /∗ on a un t a b l e a u t a b de N e n t i e r s ∗/
3 f o r ( i = 0 ; i < N ; i++ ) {
4 p r i n t f ( ” t a b [%d ] : %d \n ” , i , t a b [ i ] ) ;
5 }
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Allocation statique
La taille du tableau est connue ` a la compilation Le compilateur r´ eserve l’espace m´ emoire n´ ecessaire Le nombre d’´ el´ ements est donn´ e entre crochets : 1 i n t t a b [ 1 0 ] ;
Bonne pratique : utilisation d’une constante de compilation 1 #d e f i n e TAILLETAB 10
2 i n t t a b [ TAILLETAB ] ;
A la compilation, le pr´ ` eprocesseur remplace TAILLETAB par sa valeur Code source plus lisible
Plus facile ` a modifier ult´ erieurement R´ eutilisable dans le code
1 #d e f i n e TAILLETAB 10 2 i n t t a b [ TAILLETAB ] ; 3
4 f o r ( i = 0 ; i < TAILLETAB ; i++ ) {
5 t a b [ i ] = 0 ;
6 }
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Allocation statique
La taille du tableau est connue ` a la compilation Le compilateur r´ eserve l’espace m´ emoire n´ ecessaire Le nombre d’´ el´ ements est donn´ e entre crochets : 1 i n t t a b [ 1 0 ] ;
Bonne pratique : utilisation d’une constante de compilation 1 #d e f i n e TAILLETAB 10
2 i n t t a b [ TAILLETAB ] ;
A la compilation, le pr´ ` eprocesseur remplace TAILLETAB par sa valeur Code source plus lisible
Plus facile ` a modifier ult´ erieurement R´ eutilisable dans le code
1 #d e f i n e TAILLETAB 10 2 i n t t a b [ TAILLETAB ] ; 3
4 f o r ( i = 0 ; i < TAILLETAB ; i++ ) {
5 t a b [ i ] = 0 ;
}
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Allocation statique
La taille du tableau est connue ` a la compilation Le compilateur r´ eserve l’espace m´ emoire n´ ecessaire Le nombre d’´ el´ ements est donn´ e entre crochets : 1 i n t t a b [ 1 0 ] ;
Bonne pratique : utilisation d’une constante de compilation 1 #d e f i n e TAILLETAB 10
2 i n t t a b [ TAILLETAB ] ;
A la compilation, le pr´ ` eprocesseur remplace TAILLETAB par sa valeur Code source plus lisible
Plus facile ` a modifier ult´ erieurement R´ eutilisable dans le code
1 #d e f i n e TAILLETAB 10 2 i n t t a b [ TAILLETAB ] ; 3
4 f o r ( i = 0 ; i < TAILLETAB ; i++ ) {
5 t a b [ i ] = 0 ;
6 }
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
D´ eclaration statique et initialisation
Remplissage du tableau :
1 i n t t a b [ 3 ] = { 0 , 1 , 2 } ; Le compilateur :
R´ eserve l’emplacement en m´ emoire pour 3 cases
Les remplit avec les valeurs donn´ ees entre accolades (s´ epar´ ees par des virgules)
Autre possibilit´ e :
D´ eclaration sans la taille Initisalisation tout de suite
Le compilateur compte le nombre d’´ el´ ements donn´ es pour l’initialisation et il r´ eserve la taille n´ ecessaire
1 i n t t a b [ ] = { 0 , 1 , 2 } ;
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Allocation dynamique
La taille du tableau n’est pas connue ` a la compilation
On ne peut pas r´ eserver d’espace m´ emoire ` a la compilation On d´ eclare un tableau et on l’alloue plus tard
Utilisation d’un pointeur. Rappel : D´ efinition
Un pointeur est une adresse vers une zone m´ emoire.
i n t ∗ i ; int* i;
Non-initialis´ e, un pointeur ne pointe sur rien
Il peut pointer vers une variable : int* i = &k;
On peut allouer une zone m´ emoire vers laquelle il pointe
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Allocation dynamique
La taille du tableau n’est pas connue ` a la compilation
On ne peut pas r´ eserver d’espace m´ emoire ` a la compilation On d´ eclare un tableau et on l’alloue plus tard
Utilisation d’un pointeur. Rappel : D´ efinition
Un pointeur est une adresse vers une zone m´ emoire.
i n t ∗ i ; int* i;
Non-initialis´ e, un pointeur ne pointe sur rien
Il peut pointer vers une variable : int* i = &k;
On peut allouer une zone m´ emoire vers laquelle il pointe
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Allocation dynamique
Allocation d’une zone m´ emoire : fonction malloc() Prototype : void *malloc( size t size );
D´ efinie dans stdlib.h : #include <stdlib.h>
Retourne un pointeur vers l’espace m´ emoire allou´ e
L’espace m´ emoire allou´ e est un tampon de m´ emoire contig¨ ue Remarques :
Le type size t est un entier
malloc() retourne un pointeur de type non sp´ ecifi´ e (void*) Transtypage pour utiliser un pointeur du type d´ esir´ e Exemple :
1 #d e f i n e TAILLETAB 10
2 i n t ∗ i ;
3 i = ( i n t ∗) m a l l o c ( TAILLETAB ∗ 4 ) ;
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Allocation dynamique
Allocation d’une zone m´ emoire : fonction malloc() Prototype : void *malloc( size t size );
D´ efinie dans stdlib.h : #include <stdlib.h>
Retourne un pointeur vers l’espace m´ emoire allou´ e
L’espace m´ emoire allou´ e est un tampon de m´ emoire contig¨ ue Remarques :
Le type size t est un entier
malloc() retourne un pointeur de type non sp´ ecifi´ e (void*) Transtypage pour utiliser un pointeur du type d´ esir´ e Exemple :
1 #d e f i n e TAILLETAB 10
2 i n t ∗ i ;
3 i = ( i n t ∗) m a l l o c ( TAILLETAB ∗ 4 ) ;
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Utilisation de malloc()
Exemple pr´ ec´ edent : non portable !
Taille transmise en dur TAILLETAB * 4
Et si un entier est cod´ e sur autre chose que 4 octets ? Fonction qui retourne la taille d’un ´ el´ ement :
size t sizeof( type )
Retourne un entier (int ou size t) Prend le nom du type en argument
1 #d e f i n e TAILLETAB 10
2 i n t ∗ t a b ;
3 t a b = ( i n t ∗ ) m a l l o c ( TAILLETAB ∗ s i z e o f ( i n t ) ) ;
Attention : malloc() retourne toujours un pointeur utilisable (contrairement ` a ce que dit le man)
Si le syst` eme n’a pas pu allouer la m´ emoire : bus error lors de
l’utilisation (plantage sur SIGBUS)
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Modification de la taille d’un espace allou´ e
Utilisation de la fonction realloc()
Prototype : void* realloc(void *ptr, size t size);
Modification de la taille d’un tampon m´ emoire
Concr` etement : r´ eallocation d’un nouvel espace m´ emoire, copie du contenu de l’ancien dans le nouveau (ce qui tient dans le nouveau) Attention : le pointeur vers le tableau change
On r´ ecup` ere un nouveau pointeur en retour de la fonction
1 #d e f i n e TAILLETAB 10
2 i n t ∗ t a b ; 3 i n t t a i l l e ;
4 t a i l l e = TAILLETAB ;
5 t a b = ( i n t ∗) m a l l o c ( t a i l l e ∗ s i z e o f ( i n t ) ) ; 6 t a i l l e = t a i l l e ∗ 2 ;
7 t a b = ( i n t ∗) r e a l l o c ( t a b , t a i l l e ∗ s i z e o f ( i n t ) ) ;
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Lib´ eration de l’espace m´ emoire
La m´ emoire allou´ ee doit ˆ etre lib´ er´ ee !!
Utilisation de la proc´ edure free() Prototype : void free( void* ptr );
Le syst` eme lib` ere le tampon m´ emoire point´ e par le pointeur
1 #d e f i n e TAILLETAB 10
2 i n t ∗ t a b ;
3 t a b = ( i n t ∗) m a l l o c ( TAILLETAB ∗ s i z e o f ( i n t ) ) ; 4 f r e e ( t a b ) ;
Apr` es avoir lib´ er´ e une zone m´ emoire, il est plus sˆ ur de mettre le pointeur qui pointait dessus ` a la valeur NULL
Eviter de l’utiliser ult´ ´ erieurement par erreur 1 i f ( NULL != t a b ) {
2 f r e e ( t a b ) ; 3 t a b = NULL ;
4 }
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Repr´ esentation m´ emoire d’un tableau
D´ ebut d’un tableau = adresse contenue dans le pointeur
Puis d´ ecalage case par case suivant la taille des ´ el´ ements contenus dans le tableau
int* tab;
1 i n t ∗ t a b I ; 2 d o u b l e ∗ tabD ; 3 i n t i ;
4
5 t a b I = ( i n t ∗) m a l l o c ( TAILLETAB \
6 ∗ s i z e o f ( i n t ) ) ;
7 tabD = ( d o u b l e ∗) m a l l o c ( TAILLETAB \
8 ∗ s i z e o f ( d o u b l e ) ) ;
9
10 p r i n t f ( ” T a b l e a u d ’ e n t i e r s : \ n ” ) ;
11 f o r ( i = 0 ; i < TAILLETAB ; i++ ) {
12 p r i n t f ( ”%d : %p\ n ” , i , &( t a b I [ i ] ) ) ; 13 }
14
15 p r i n t f ( ” T a b l e a u de d o u b l e s :\ n ” ) ;
16 f o r ( i = 0 ; i < TAILLETAB ; i++ ) {
17 p r i n t f ( ”%d : %p\ n ” , i , &(tabD [ i ] ) ) ; 18 }
Affichage obtenu :
T a b l e a u d ’ e n t i e r s :
0 : 0 x 1 0 0 1 0 0 0 8 0
1 : 0 x 1 0 0 1 0 0 0 8 4
2 : 0 x 1 0 0 1 0 0 0 8 8
3 : 0 x 1 0 0 1 0 0 0 8 c
4 : 0 x 1 0 0 1 0 0 0 9 0
T a b l e a u de d o u b l e s :
0 : 0 x 1 0 0 1 0 0 0 a 0
1 : 0 x 1 0 0 1 0 0 0 a 8
2 : 0 x 1 0 0 1 0 0 0 b 0
3 : 0 x 1 0 0 1 0 0 0 b 8
4 : 0 x 1 0 0 1 0 0 0 c 0
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Tableau ` a plusieurs dimensions
Utilisation d’un tableau de pointeurs sur des tableaux : int** tab;
int* tab[2];
int* tab[1];
int* tab[0];
Exemple : tableau d’entiers ` a 2 dimensions
D´ eclaration d’un pointeur sur un tableau de pointeurs sur des entiers Alloction du tableau de pointeurs
Allocation de tous les tableaux sur entiers
#d e f i n e LIGNES 3
#d e f i n e COLONNES 5 i n t ∗∗ t a b 2 d ; i n t i ;
t a b 2 d = ( i n t ∗ ∗ ) m a l l o c ( LIGNES \
∗ s i z e o f ( i n t ∗ ) ) ;
f o r ( i = ; i < LIGNES ; i++ ) {
t a b 2 d [ i ] = ( i n t ∗ ) m a l l o c ( COLONNES \
∗ s i z e o f ( i n t ) ) ; }
Acc` es :
tab[i] d´ esigne la i-` eme ligne → pointeur vers le tableau correspondant ` a la ligne
tab[i][j] d´ esigne la j-` eme case du tableau de la ligne i
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Tableau ` a plusieurs dimensions
Utilisation d’un tableau de pointeurs sur des tableaux : int** tab;
int* tab[2];
int* tab[1];
int* tab[0];
Exemple : tableau d’entiers ` a 2 dimensions
D´ eclaration d’un pointeur sur un tableau de pointeurs sur des entiers Alloction du tableau de pointeurs
Allocation de tous les tableaux sur entiers
#d e f i n e LIGNES 3
#d e f i n e COLONNES 5 i n t ∗∗ t a b 2 d ; i n t i ;
t a b 2 d = ( i n t ∗ ∗ ) m a l l o c ( LIGNES \
∗ s i z e o f ( i n t ∗ ) ) ;
f o r ( i = ; i < LIGNES ; i++ ) {
t a b 2 d [ i ] = ( i n t ∗ ) m a l l o c ( COLONNES \
∗ s i z e o f ( i n t ) ) ; }
Acc` es :
tab[i] d´ esigne la i-` eme ligne → pointeur vers le tableau correspondant ` a
la ligne
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Parcours d’un tableau
Utilisation de l’indice entre crochets
tab d´ esigne l’adresse du d´ ebut d’un tableau tab[i] d´ esigne la i-` eme case du tableau
&(tab[i]) d´ esigne l’adresse de la i-` eme case du tableau
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Arithm´ etique de pointeurs
Si on d´ eclare un tableau int* tab
tab d´ esigne l’adresse du 1er ´ el´ ement du tableau
´ Equivalent ` a &( tab[0] )
*tab d´ esigne l’´ el´ ement point´ e par tab
´ Equivalent ` a tab[0]
On acc` ede ` a l’´ el´ ement suivant en ajoutant 1 au pointeur tab+1 pointe sur l’´ el´ ement qui suit l’´ el´ ement point´ e par tab
*(tab+1) d´ esigne l’´ element point´ e par tab+1, donc tab[1]
On peut effectuer des op´ erations arithm´ etiques sur un pointeur. Exemple :
1 #d e f i n e TAILLETAB 10
2 i n t t a b [ TAILLETAB ] ; 3 i n t∗ p ;
4 i n t i ; 5 p = t a b ;
6 f o r( i = 0 ; i < TAILLETAB ; i++ ) {
7 p r i n t f ( ” A d r e s s e : %p ” , p ) ; 8 p r i n t f ( ” V a l e u r : %d\n ” , ∗p ) ;
9 p++;
10 }
p est initialis´ e ` a l’adresse de d´ ebut du tableau (ligne 5)
On incr´ emente p ligne 9 : on
passe ` a l’´ el´ ement suivant
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Application aux chaˆınes de caract` eres
Chaˆıne de caract` eres = tableau de caract` eres
Exemple : Coucou C o u c o u “0
Le dernier ´ el´ ement est le caract` ere sp´ ecial “0 Caract` ere de fin de chaˆıne de caract` eres
Attention : pour une chaˆıne de N caract` eres, il faut donc un tableau de taille N+1
D´ eclaration d’une chaˆıne de caract` eres : char* chaine;
Op´ erations sur des chaines de caract` eres : la plupart d´ eclar´ ees dans string.h
#include <string.h>
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Op´ erations sur les chaˆınes de caract` eres
Longueur d’une chaine de caract` eres : size t strlen( char* str );
Prend en param` etre une chaˆıne de caract` eres Retourne un entier de type size t
Copie d’une chaˆıne de caract` eres :
char* strcpy( char* dest, char* orig );
Copie orig dans dest
Retourne dest : souvent inutilis´ e La chaˆıne dest doit ˆ etre allou´ ee
Attention : strcpy n’est pas sˆ ur (risques de d´ ebordement de tampons, exploitable comme une faille de s´ ecurit´ e)
Utilisation de strncpy( )
Prototype : char* strncpy( char* dest, char* orig, size t taille );
Copie taille caract` eres de orig dans dest
Copie brute d’un tampon dans un autre :
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Op´ erations sur les chaˆınes de caract` eres
Longueur d’une chaine de caract` eres : size t strlen( char* str );
Prend en param` etre une chaˆıne de caract` eres Retourne un entier de type size t
Copie d’une chaˆıne de caract` eres :
char* strcpy( char* dest, char* orig );
Copie orig dans dest
Retourne dest : souvent inutilis´ e La chaˆıne dest doit ˆ etre allou´ ee
Attention : strcpy n’est pas sˆ ur (risques de d´ ebordement de tampons, exploitable comme une faille de s´ ecurit´ e)
Utilisation de strncpy( )
Prototype : char* strncpy( char* dest, char* orig, size t taille );
Copie taille caract` eres de orig dans dest Copie brute d’un tampon dans un autre :
void *memcpy( void *dest, void *orig, size t n );
Allocation de tableaux D´eclaration de nouveaux types Allocation statique Allocation dynamique Utilisation
Op´ erations sur les chaˆınes de caract` eres
Longueur d’une chaine de caract` eres : size t strlen( char* str );
Prend en param` etre une chaˆıne de caract` eres Retourne un entier de type size t
Copie d’une chaˆıne de caract` eres :
char* strcpy( char* dest, char* orig );
Copie orig dans dest
Retourne dest : souvent inutilis´ e La chaˆıne dest doit ˆ etre allou´ ee
Attention : strcpy n’est pas sˆ ur (risques de d´ ebordement de tampons, exploitable comme une faille de s´ ecurit´ e)
Utilisation de strncpy( )
Prototype : char* strncpy( char* dest, char* orig, size t taille );
Copie taille caract` eres de orig dans dest
Copie brute d’un tampon dans un autre :
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
1
Allocation de tableaux Allocation statique Allocation dynamique Utilisation
2
D´ eclaration de nouveaux types Structure
Enum´ ´ eration
Remarque : taille
Type d´ eriv´ e
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
D´ efinition d’une structure
D´ efinition d’une structure de donn´ ees contenant des ´ el´ ements de types diff´ erents
1 s t r u c t m a S t r u c t { 2 t y p e 1 champ1 ; 3 t y p e 2 champ2 ; 4 . . .
5 } ; Syntaxe
Utilisation du mot-cl´ e struct Nom de la structure D´ efinition des champs
Attention au point-virgule final Exemple :
1 s t r u c t e t u d i a n t {
2 c h a r nom [ 2 5 6 ] ;
3 c h a r prenom [ 2 5 6 ] ;
4 i n t d a t e D e N a i s s a c e [ 3 ] ;
5 } ;
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
Utilisation d’une structure
D´ eclaration d’un ´ el´ ement du type de la structure : struct + nom de la structure + nom de la variable Exemple :
1 s t r u c t e t u d i a n t { 2 c h a r nom [ 2 5 6 ] ; 3 c h a r prenom [ 2 5 6 ] ; 4 i n t d a t e D e N a i s s a c e [ 3 ] ; 5 } ;
6
7 s t r u c t e t u d i a n t e t 1 ;
Possibilit´ e d’utiliser des structures dans les champs d’une structure 1 s t r u c t d a t e {
2 i n t j o u r ; 3 i n t m o i s ; 4 i n t a n n e e ; 5 } ;
1 s t r u c t e t u d i a n t { 2 c h a r nom [ 2 5 6 ] ; 3 c h a r prenom [ 2 5 6 ] ;
4 s t r u c t d a t e d a t e D e N a i s s a c e ;
5 } ;
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
Utilisation d’une structure
D´ eclaration d’un ´ el´ ement du type de la structure : struct + nom de la structure + nom de la variable Exemple :
1 s t r u c t e t u d i a n t { 2 c h a r nom [ 2 5 6 ] ; 3 c h a r prenom [ 2 5 6 ] ; 4 i n t d a t e D e N a i s s a c e [ 3 ] ; 5 } ;
6
7 s t r u c t e t u d i a n t e t 1 ;
Possibilit´ e d’utiliser des structures dans les champs d’une structure 1 s t r u c t d a t e {
2 i n t j o u r ; 3 i n t m o i s ; 4 i n t a n n e e ; 5 } ;
1 s t r u c t e t u d i a n t { 2 c h a r nom [ 2 5 6 ] ; 3 c h a r prenom [ 2 5 6 ] ;
4 s t r u c t d a t e d a t e D e N a i s s a c e ;
5 } ;
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
Utilisation d’une structure (suite)
Acc` es aux champs de la structure :
nom de la variable + point (.) + nom du champ Exemple :
1 s t r u c t e t u d i a n t e t 1 ;
2 e t 1 . d a t e D e N a i s s a c e = { 0 , 0 , 0 } ;
Cas d’un pointeur
Si on d´ eclare un pointeur vers un ´ el´ ement du type de cette structure Utilisation d’une fl` eche (->) pour acc´ eder ` a ses champs
1 s t r u c t e t u d i a n t ∗ e t 2 ;
2 e t 2 = ( s t r u c t e t u d i a n t ∗) m a l l o c ( s i z e o f ( e t u d i a n t ) ) ;
3 e t 2 − >d a t e D e N a i s s a c e = { 0 , 0 , 0 } ;
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
D´ eclaration d’une ´ enum´ eration
On d´ eclare une ´ enum´ eration en ´ enum´ erant les valeurs possibles de ses variables
Utilisation du mot-cl´ e enum
Enum´ ´ eration de toutes les valeurs possibles
Le compilateur se charge de convertir dans le type de donn´ ees interne le plus ad´ equat (g´ en´ eralement un entier)
Exemple :
1 enum c o u l e u r { ROUGE, VERT , BLEU } ; Possibilit´ e de forcer la valeur interne prise par chaque valeur Exemple :
1 enum b o o l e e n {
2 TRUE = 1 ,
3 FALSE = 0
4 } ;
Utilisation : enum + nom de l’´ enum´ eration + nom de la variable
1 enum c o u l e u r c1 = ROUGE ;
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
Remarque sur la taille des structures
La taille de la zone m´ emoire occup´ ee par une structure n’est pas forc´ ement
´ egale ` a la somme des tailles des champs qui la composent ! 1 s t r u c t s t r 1 {
2 c h a r c1 ;
3 i n t i 1 ;
4 c h a r c2 ;
5 i n t i 2 ;
6 } ;
1 s t r u c t s t r 2 {
2 c h a r c1 ;
3 c h a r c2 ;
4 i n t i 1 ;
5 i n t i 2 ;
6 } ;
Le compilateur aligne les donn´ ees des champs des structures Blocs de 4 octets
Bourrage entre les champs
p r i n t f ( ” s t r 1 : %d , s t r 2 : %d \n ” , s i z e o f ( s t r u c t s t r 1 ) , s i z e o f ( s t r u c t s t r 2 ) ) ; Affichage obtenu :
s t r 1 : 1 6 , s t r 2 : 12
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
Occupation m´ emoire des structures
1 s t r u c t s t r 1 {
2 c h a r c1 ;
3 i n t i 1 ;
4 c h a r c2 ;
5 i n t i 2 ;
6 } ;
c1 i1 c2
i2
0 1 2 3 4
0 1 2 3 4
1 s t r u c t s t r 2 {
2 c h a r c1 ;
3 c h a r c2 ;
4 i n t i 1 ;
5 i n t i 2 ;
6 } ;
c1 c2 i1 i2
0 1 2 3 4
0
1
2
3
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
Eviter le bourrage ` ´ a la compilation
NB : le bourrage a un int´ erˆ et
Optimisation pour aligner les donn´ ees sur les structures internes du CPU et la m´ emoire de la machine
Transferts de donn´ ees m´ emoire ↔ CPU plus rapides
Le compilateur gcc peut pr´ evenir l’utilisateur en cas de bourrage dans une structure :
Option -Wpadded : affiche un avertissement (warning) si une structure est bourr´ ee (padded)
$ g c c −Wpadded −o t a i l l e s S t r u c t t a i l l e s S t r u c t . c
On peut demander ` a gcc de ”packer” les structures Pas de bourrage utilis´ e
Option -fpack-struct
$ g c c −f p a c k−s t r u c t −o t a i l l e s S t r u c t t a i l l e s S t r u c t . c
Toutes les structures du programme seront pack´ ees.
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
Eviter le bourrage ` ´ a la compilation
NB : le bourrage a un int´ erˆ et
Optimisation pour aligner les donn´ ees sur les structures internes du CPU et la m´ emoire de la machine
Transferts de donn´ ees m´ emoire ↔ CPU plus rapides
Le compilateur gcc peut pr´ evenir l’utilisateur en cas de bourrage dans une structure :
Option -Wpadded : affiche un avertissement (warning) si une structure est bourr´ ee (padded)
$ g c c −Wpadded −o t a i l l e s S t r u c t t a i l l e s S t r u c t . c
On peut demander ` a gcc de ”packer” les structures Pas de bourrage utilis´ e
Option -fpack-struct
$ g c c −f p a c k−s t r u c t −o t a i l l e s S t r u c t t a i l l e s S t r u c t . c
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
Eviter le bourrage ` ´ a la compilation
NB : le bourrage a un int´ erˆ et
Optimisation pour aligner les donn´ ees sur les structures internes du CPU et la m´ emoire de la machine
Transferts de donn´ ees m´ emoire ↔ CPU plus rapides
Le compilateur gcc peut pr´ evenir l’utilisateur en cas de bourrage dans une structure :
Option -Wpadded : affiche un avertissement (warning) si une structure est bourr´ ee (padded)
$ g c c −Wpadded −o t a i l l e s S t r u c t t a i l l e s S t r u c t . c
On peut demander ` a gcc de ”packer” les structures Pas de bourrage utilis´ e
Option -fpack-struct
$ g c c −f p a c k−s t r u c t −o t a i l l e s S t r u c t t a i l l e s S t r u c t . c
Toutes les structures du programme seront pack´ ees.
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
Eviter le bourrage en programmant ´
On peut d´ efinir les structures individuellement comme pack´ ees en donnant une directive de compilation
__attribute__((packed)) Seule cette structure sera pack´ ee
Les structures qui sont d´ efinies sans cette directive de compilation ne le seront pas
1 s t r u c t s t r 1 {
2 c h a r c1 ;
3 i n t i 1 ;
4 c h a r c2 ;
5 i n t i 2 ;
6 } a t t r i b u t e ( ( p a c k e d ) ) ;
Affichage obtenu en packant toutes les structures de donn´ ees :
s t r 1 : 1 0 , s t r 2 : 10
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
D´ efinition d’un type d´ eriv´ e
D´ efinition d’un nouveau type : Utilisation du mot-cl´ e typedef Ancien type + nouveau type
Red´ efinition d’un type existant
1 t y p e d e f i n t e n t i e r ;
D´ efinition d’un type associ´ e ` a une structure
1 t y p e d e f s t r u c t e t u d i a n t e t u d i a n t t ;
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
D´ efinition d’un type d´ eriv´ e
D´ efinition d’un nouveau type : Utilisation du mot-cl´ e typedef Ancien type + nouveau type
Red´ efinition d’un type existant
1 t y p e d e f i n t e n t i e r ;
D´ efinition d’un type associ´ e ` a une structure
1 t y p e d e f s t r u c t e t u d i a n t e t u d i a n t t ;
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
D´ efinition d’un type d´ eriv´ e
D´ efinition d’un nouveau type : Utilisation du mot-cl´ e typedef Ancien type + nouveau type
Red´ efinition d’un type existant
1 t y p e d e f i n t e n t i e r ;
D´ efinition d’un type associ´ e ` a une structure
1 t y p e d e f s t r u c t e t u d i a n t e t u d i a n t t ;
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e
D´ efinition d’un type d´ eriv´ e (suite)
On peut d´ efinir le type en mˆ eme temps que la structure : Exemple avec une ´ enum´ eration :
1 t y p e d e f enum { TRUE , FALSE } b o o l e e n ;
Utilisation :
1 b o o l e e n b1 = TRUE ; Exemple avec une structure :
1 t y p e d e f s t r u c t { 2 i n t j o u r ; 3 i n t m o i s ; 4 i n t a n n e e ; 5 } d a t e t ; Utilisation du type
On utilise directement le nom du type
1 d a t e t d1 ;
Allocation de tableaux D´eclaration de nouveaux types Structure ´Enum´eration Remarque : taille Type d´eriv´e