UKOnline

Définition et utilisation

Une structure doit être définie avant de pouvoir être utilisée. Pour cela, on utilise le mot réservé struct et on définit la nouvelle structure en dehors de toute procédure ou fonction. Une structure est identifiée par un nom et par une liste de champs. Prenons un exemple de structure qui permet de stocker deux informations à propos d'une personne, à savoir son sexe et son âge.

Le nom de cette nouvelle structure est info et elle possède deux champs. Un champ est simplement une variable, et la déclaration d'un champ est donc une déclaration de variable. Le premier champ est la variable nommée age de type int et le second champ est la variable nommée sex de type char.

Une structure permet donc de rassembler plusieurs variables dans un nouveau type de données, identifié par un nom. C'est en quelque sorte comme les tableaux, si ce n'est qu'on peut ici avoir des types de données différents.

Déclaration

Une fois la structure définie, on va pouvoir l'utiliser, c'est-à-dire déclarer des nouvelles variables de ce type. La déclaration se fait comme on l'a toujours vu, c'est-à-dire qu'on écrit le type que l'on souhaite suivi du nom de la variable. Déclarons par exemple une nouvelle variable appelée var, et de type struct info :

Cette instruction a donc déclaré la variable var, et son contenu est indéterminé. La figure 1 illustre la variable qui a été créée, et on y voit bien les deux champs.

Déclaration de structure
Exemple de déclaration d'une variable de type structure.

Le nom de la structure et le nom des champs doivent évidemment respecter la règle de hommage d'un identificateur qu'on a vue à la section 2 du premier chapitre. Enfin, il ne peut pas y avoir plusieurs structures avec le même nom dans le même programme.

Opérateur d'accès aux champs

Une fois une variable de type structure est déclarée, il faut l'initialiser, c'est-à-dire initialiser chacun de ses champs. Lorsqu'on a une variable dont le type est une structure, on peut accéder aux différents champs avec l'opérateur d'accès qui est le point ( . ). En faisant suivre le nom de la variable par un point et puis par le nom du champ qui nous intéresse, on peut accéder à la valeur du champ et également la modifier.

Initialisation d'une structure

Voici par exemple comment initialiser la variable var pour qu'elle représente une femme de 21 ans :

La figure 2 montre la variable une fois complètement initialisée. On peut en effet voir que les deux champs possèdent une valeur. Il est évidemment possible de n'initialiser que certains des champs d'une structure.

Initialisation de structure
Exemple d'initialisation d'une variable de type structure.

L'opérateur d'accès donne donc accès à un champ, et on peut ainsi faire toutes les opérations qu'on a déjà vues, s'appliquant sur des variables. Par exemple, on peut tester la valeur d'un champ dans une condition comme le montre l'exemple suivant :

On teste donc si la valeur du champ age de la variable var est strictement plus petite que 12 et si la valeur du champ sex est égal à 'F'.

Modification d'une structure

Voyons un autre exemple de structure, qui permet de représenter un point dans le temps. Cette structure time a deux champs hour et minute de type short représentant respectivement les heures et les minutes du point dans le temps.

Une fois une variable de type structure déclarée et la structure complètement initialisée, il est encore possible de modifier la valeur de ses champs. Pour cela, on utilise simplement l'opérateur d'affectation sur le champ dont on veut modifier la valeur. La figure 3 montre un exemple complet de programme qui utilise une structure. L'exécution du programme affiche à l'écran :

Il est 08:57.
Il est 09:07.

On voit donc qu'il y a dix minutes d'écart entre les deux temps affichés. Passons en revue les points essentiels de ce programme :

  • Les lignes 3 à 6 définissent la structure time. Remarquez bien que la définition doit se terminer par un point-virgule sans quoi une erreur de compilation sera produite.
  • Les lignes 10 à 12 déclarent une nouvelle variable t de type struct time et l'initialisent pour représenter 8h57. La ligne 14 affiche les valeurs des deux champs de la structure.
  • Les lignes 16 à 25 permettent de simuler le temps qui passe. Il s'agit d'une boucle qui va ajouter une minute au temps, dix fois (pour un total de 10 minutes donc). Évidemment, si les minutes atteignent 60, il faut les remettre à zéro et ajouter une heure.
  • Enfin, la ligne 27 affiche den nouveau les valeurs des deux champs de la structure.
Exemple de programme manipulant une variable de type structure.

Paramètre et type de retour de type structure

Voyons enfin une dernière utilisation de base des structures. On peut évidemment utiliser une structure comme paramètre d'une procédure ou fonction, et également comme type de retour d'une fonction.

Paramètre de type structure

Commençons par voir un exemple de fonction qui prend en paramètre une variable de type structure. On va définir une fonction qui reçoit une structure de type struct time en paramètre et qui permet de tester si l'heure représentée fait partie de la matinée (entre 8h et 12h, même si, précisément, la matinée se définit comme la partie du jour comprise entre le lever du jour et midi). Voici la définition de la fonction :

La fonction reçoit un paramètre t de type struct time et doit renvoyer un bool. On teste donc que l'heure est bien comprise entre 8 et 12 en accédant au champ hour de la structure en écrivant t.hour. Tout comme lorsqu'on passe en paramètre une simple variable, la structure est complètement copiée lors de l'appel à la fonction. On peut donc modifier le paramètre sans que cela n'altère celle qui a été passée au moment de l'appel.

Voyons maintenant un second exemple. La procédure suivante reçoit un paramètre de type structure et va l'afficher proprement à l'écran.

Il n'y a pas de balises prédéfinies pour la fonction printf permettant d'afficher une structure, et c'est normal puisque les structures peuvent être, par définition, toutes différentes. Dès lors, c'est assez souvent une bonne pratique de définir une procédure permettant d'afficher proprement une structure.

Type de retour de type structure

On peut évidemment aussi définir des fonctions dont le type de retour est une structure. Voyons par exemple une fonction qui permet de déclarer et initialiser une structure. La fonction reçoit deux paramètres de type short, pour les heures et minutes. Elle déclare ensuite une nouvelle variable de type struct time, puis initialise les deux champs avec les paramètres reçus. Enfin, elle renvoie la nouvelle structure ainsi créée et initialisée.

Utilisation de procédures et fonctions avec des structures

Terminons enfin cette section en voyant comment on utilise en pratique les différentes procédures et fonctions qu'on a définies dans cette section. Dans le code suivant, on commence par créer une nouvelle structure représentant 8h57 en appelant la fonction createTime. Ensuite, on teste si cette heure fait partie de la matinée en appelant la fonction isMorning, et en stockant son résultat dans la variable morning. Enfin, on affiche l'heure avec la procédure printTime, suivie de la valeur de la variable morning.

Définition de type

Devoir à chaque fois écrire struct nom_de_la_structure comme type de variable est long et peut rendre un code moins lisible. En utilisant l'instruction typedef vue précédemment, il est possible de définir un nom raccourci pour les nouvelles structures qu'on définit dans un programme. On pourra par exemple écrire :

Une fois cette déclaration faite, on pourra donc, pour rappel, utiliser TIME au lieu de struct time. Par exemple, on peut déclarer une nouvelle variable de type TIME et l'initialiser pour représenter 10h51 comme suit :

Enfin, il est possible de directement combiner la définition d'une nouvelle structure avec l'instruction typedef en une seule fois, afin d'avoir un code plus compact. On pourrait donc également écrire :

Cette instruction fait deux choses à la fois : elle définit la nouvelle structure (on pourra donc utiliser struct time) et elle définit un nouveau type sur base de cette structure (on pourra donc utiliser TIME).