Table des matières
Structures
Présentation
Une structure est un regroupement, une sorte de paquet de plusieurs données.
struct s_personne
{
int age;
char nom[20];
};
La structure s_personne est un nouveau type. Une variable de type s_personne contient deux sous-données, ici un entier age et une chaîne nom.
parenté avec les classes
Cette présentation évoque les classes. On peut voir les structures comme une version simplifiée des classes.
Mais on n'a pas, pour les structures, tous les outils qui rendent les classes aussi pratiques : méthodes, privé / public, constructeur, …
Création d'une variable
Supposons que je veuille créer une variable p de type s_personne,
déclaration d'une variable p
struct s_personne p;
Nous sommes obligés de préciser le mot-clé struct pour indiquer que ce n'est pas un type de base mais un type nouveau.
Sur C playground ce n'est pas nécessaire de précisertstruct. Cela dépend probablement du compilateur : il semble que C playground utilise un compilateur C++ ce qui occasionne quelques différences. Mais en C, il faut bien préciser le mot-cléstruct, sauf si on fait ce qui suit.
Pour alléger la déclaration, on peut choisir de définir une sorte d'étiquette :
typedef struct s_personne
{
int age;
char nom[20];
} personne;
Cela signifie que l'on a attaché l'étiquette personne à la structure s_personne. Alors on peut déclaré une variable :
déclaration de p avec l'étiquette
personne p; // on utilise l'étiquette
Mais ce que l'on fait le plus souvent, c'est que l'on donne le même nom à la structure et à l'étiquette ce qui donne des déclarations un peu étrange comme ceci :
typedef struct personne
{
int age;
char nom[20];
} personne;
int main()
{
personne p;
...
return 0;
}
Pour la suite de mes exemples, je considérais la structure définie comme ci-dessus, avec le nompersonnecomme étiquette et identifiant de structure.
Accès aux attributs
On parle aussi de membres.
Modifier p ou lire p c'est avant tout agir sur ses attributs age et nom.
initialisation
On peut d'abord initialisé la variable de cette façon :
initialisation à la déclaration
personne p = { 72, "Robert" };
On peut aussi spécifier les attributs ce qui permet de choisir l'ordre :
initialisation à la déclaration
personne p = { .nom = "Robert", .age = 72 };
On peut aussi n'initialiser qu'une partie des attributs :
initialisation à la déclaration
personne p = { .nom = "Robert" };
Dans ce cas, l'age est par défaut à 0.
Lecture / modification
La notation est semblable à celles des attributs de classe en Python : on notera p.age et p.nom pour les deux attributs.
accès aux attributs
personne p = { .nom = "Robert", .age = 72 };
printf("Le nom est %s.\n", p.nom);
printf("L'age est %d.\n", p.age);
Accès avec un pointeur
Il est très fréquent que l'on doive travailler sur une structure via un pointeur.
Plaçons nous dans le cas où p est toujours la variable de type personne et poi un pointeur sur p.
personne p = { .nom = "Robert", .age = 72 };
personne *poi = &p;
Vous constatez que ligne 2 que poi pointe sur l'adresse &p, c'est à dire l'adresse de la case mémoire où commence la structure p.
poccupe plusieurs cases mémoires puisqu'il est composé d'un entier et d'un tableau de caractères. Le pointeur donne l'adresse du début.
On peut accéder aux attributs de p directement à partir de poi. Pour cela, au lieu de la notation avec un ., on utilise ->. Cette flèche exprime l'idée que le pointeur est une flèche qui pointe sur une case mémoire.
personne p = { .nom = "Robert", .age = 72 };
personne *poi = &p;
printf("Le nom est %s.\n", poi->nom);
printf("L'age est %d.\n", poi->age);
