Travaux dirigés 5
|
Lorsqu'on déclare int *p; on déclare un pointeur vers un entier, c'est-à-dire que p contient l'adresse de la zone mémoire oł est stocké cet entier.
Par exemple, la séquence suivante :
int v,*p;
v = 5;
p = &v;
peut avoir la représentation suivante en mémoire (en supposant que l'adresse de v
est 30 et que l'adresse de p est 10) :
adresse | contenu | |
... | ... | |
&p=10 | p=&v=30 | |
... | ... | |
p=&v=30 | *p=v=5 | |
... | ... |
La réservation "dynamique" de la mémoire s'effectue grâce aux fonctions suivantes :
Attention : ne jamais libérer une zone mémoire déjà libérée. Le système pourrait alors générer des erreurs de nature imprévisible.
Une structure est un ensemble de variables de types éventuellement différents adapté à une gestion spécifique des données.
Par exemple, pour gérer les coordonnées d'un point en abscisse et ordonnée, on pourra créer la structure suivante :
struct point {
int x;
int y;
};
Attention : le point-virgule est nécessaire après l'accolade fermante de la déclaration de la structure.
Exemple :
struct point pt; /* Le type de la variable pt est struct point */
Un tableau peut être initialisé au moment de sa déclaration en indiquant la liste de ses valeurs.
Exemples :
Pour initialiser la variable pt de type struct point déclarée précédemment, on peut utiliser la syntaxe suivante :
pt.x = 20;
pt.y = 30;
Il est également possible d'initialiser une structure au moment de sa déclaration, en
donnant la liste des valeurs de ses champs, de la même manière que pour un tableau. En
reprenant l'exemple précédent, au moment de déclarer la variable pt, on peut
écrire :
struct point pt={20,30};
: Ce type d'initialisation n'est correct
qu'au moment de la déclaration d'une variable. Il ne peut pas être utilisé ailleurs
dans un programme.
Définir une structure permettant de gérer une adresse du type :
nom, prénom, numéro de rue, nom de rue, code postal, ville.
Déclarer une variable ayant pour type cette structure et demander à l'utilisateur de
l'initialiser.
L'opérateur '.' est prioritaire sur l'opérateur '*'.
Exemple :
struct point pt,*pp;
pp = &pt;
On a alors les identités suivantes :
(*pp).x == pt.x et (*pp).y == pt.y
Par contre, l'identité *pp.x == pt.x est illégale puisqu'elle est équivalente
à *(pp.x)==pt.x et que pt.x n'est pas un pointeur.
On peut utiliser une notation permettant d'éviter les confusions :
p->a : "contenu du champ a de la structure pointée par p"
Exemple : pp->x == (*pp).x
Conformément à l'exemple ci-dessus, pt.x est une notation correcte, mais pt->x
ne l'est pas (pt n'est pas un pointeur vers une structure).
Une liste chaînée est composée d'éléments de type structure reliés entre eux par
des pointeurs.
Par exemple, on peut choisir de représenter une courbe par une liste de points :
struct courbe {
struct point pt;
struct courbe *suivant;
};
Soit trois points p1, p2 et p3 de coordonnées respectives (10,20), (30,20), (20,10). Donner l'initialisation du triangle construit à partir de p1,p2,p3 en initialisant trois variables (respectivement c1,c2 et c3) du type "struct courbe" défini précédemment.
Questions complémentaires :
Afin de donner une représentation de la manière dont les structures sont liées les unes aux autres dans la mémoire centrale d'un ordinateur lors de l'exécution d'un programme, on produit un graphique respectant les conventions suivantes :
Exemples :
Soit le programme suivant :
#include "stdio.h"
struct s1 {
char c[4];
char *s;
};
struct s1 st1 = {"abc","def"};
struct s2 {
char *cp;
struct s1 ss1;
} st2 = {"ghi",{"jkl","mno"}};
main()
{
printf("%c %c\n",st1.c[0],*st1.s);
printf("%s %s\n",st1.c, st1.s);
printf("%s %s\n",st2.cp,st2.ss1.s);
st2.cp=st2.cp+1;
st2.ss1.s=st2.ss1.s+1;
printf("%s %s\n",st2.cp,st2.ss1.s);
}
Donner la représentation des données dans la mémoire centrale et les résultats
affichés sur stdout.
Soit le programme suivant :
#include "stdio.h"
struct s1 {
char *s;
int i;
struct s1 *s1p;
};
struct s1 a[3] =
{{"abcd",1,a+1},{"efgh",2,a+2},{"ijkl",3,a}};
main()
{
struct s1 *p = a;
printf("%s %s %s\n", a[0].s, p->s, a[2].s1p->s);
}
Donner les résultats affichés sur stdout et la représentation des données dans la
mémoire centrale.
Ces pages ont été adaptées à partir de celles réalisées par J.D. Durou et Ph. Joly avec leur aimable autorisation.