< Les fonction d'entrée/sortie | TutoCFrench | Les fonctions de manipulation de fichiers >
Notions :
struct
enum
union
typedef
.
et ->
Une structure est une juxtaposition de plusieurs données regroupées en une entité.
La déclaration d'une structure se fait par le mot réservé struct
suivi d'une liste de déclaration de variables entre accolades. Attention au ;
à la fin des accolades ! :
struct
nom
{
type
champ1;
type
champ2;
type
champn;
};
Par exemple :
struct employe { int age; char profession[50]; int salaire; };
Note : en principe, on définit une structure en dehors de la fonction main
pour lui donner une portée globale.
Il est possible d'affecter une structure lors de sa déclaration :
struct employe robert = {32, "informaticien", 1200};
Contrairement aux tableaux, il est possible d'utiliser l'opérateur =
pour affecter une structure à partir d'une autre :
struct employe lucien, robert = {32, "informaticien", 1200}; lucien = robert;
Pour accèder aux membres de la structure, on utilise l'opérateur '.
' (point) concaténé au nom de la structure. Cela permet d'affecter une structure élément par élément :
struct employe robert; robert.age = 32; strcpy(robert.profession, "informaticien"); robert.salaire = 1200; printf("Robert a %d ans et il est %s\n", robert.age, robert.profession);
Attention, on ne peut utiliser les opérateurs arithmétiques ou les opérateurs de comparaison sur des structures.
Les éléments d'une structure peuvent aussi être des portions d'entiers, ce qui permet de stocker plusieurs variables sur un seul entier (économie de place). On parle de champs de bits pour qualifier ces données plus petites :
struct candidat { char sexe : 1; char age : 7; char profession[50]; int salaire; };
Il est possible de créer le type pointeur de structure et d'accèder aux membres d'une structure à partir d'un pointeur sur celle ci :
struct employe *p; p = &robert; printf("Robert est %s\n", (*p).profession);
Mais l'ecriture précédente est complexe. Une facilité est offerte par l'opérateur ->
. Ainsi, les deux écritures ci-dessous sont équivalentes :
On aurait donc pu écrire :
printf("Robert est %s\n", p->profession);
Les unions permettent de stocker un choix de plusieurs choses en une même zone mémoire. La définition d'une union est semblable à celle d'une structure, de même que la syntaxe d'accès. La différence est qu'on ne peut stocker qu'un seul élément à la fois.
Une énumération permet de définir des constantes pour une liste de valeurs. Le compilateur assigne une valeur par défaut à chaque élément de la liste en commençant par 0 et en incrémentant à chaque fois. Par exemple :
enum statut_marital { celibataire, marie, divorce, veuf };
Il est aussi possible d'assigner explicitement des valeurs :
enum statut_marital { celibataire = 1, marie = 2, divorce = 3, veuf = 4 };
La variable s'utilise alors comme dans l'exemple suivant :
struct candidat { char sexe : 1; char age : 7; enum statut_marital statut_m; char profession[50]; int salaire; }; struct candidat paul; paul.statut_m = celibataire;
typedef
Cette directive permet d'assigner un nouveau nom à un type de données au choix. On l'utilise par commodité :
typedef struct employe Employe; Employe robert = {32, "informaticien", 1200};
#include <stdio.h> #include <string.h> struct Personne { char nom[32]; char telephone[16]; }; struct Carnet { struct Personne personne[20]; int n; }; struct Personne creer_personne(char nom[], char telephone[]) { struct Personne nouv_p; strcpy(nouv_p.nom, nom); strcpy(nouv_p.telephone, telephone); return nouv_p; } void afficher_personne(struct Personne p) { printf("Nom: %s\tTelephone: %s\n", p.nom, p.telephone); return; } void ajouter_personne(struct Carnet *c, struct Personne p) { if (c->n < 20) { c->personne[c->n] = p; c->n++; } else printf("Carnet plein\n"); return; } void afficher_carnet(struct Carnet c) { int i; for (i=0; i<c.n; i++) afficher_personne(c.personne[i]); return; } struct Personne* chercher_personne(struct Carnet *c, char nom[]) { int i; for (i=0; i<c->n; i++) { if (strcmp(nom, c->personne[i].nom) == 0) return &c->personne[i]; } return NULL; } int main() { struct Personne nouv_p, *pp; struct Carnet carnet; char nom[32], telephone[16]; char choix; /* initialisation */ carnet.n = 0; while (1) { printf("(a)fficher, (i)nsérer, (c)hercher, (q)uitter\n"); printf("> "); choix = getchar(); switch(choix) { case 'a' : afficher_carnet(carnet); break; case 'i' : printf("nom> "); scanf("%s", nom); printf("telephone> "); scanf("%s", telephone); nouv_p = creer_personne(nom, telephone); ajouter_personne(&carnet, nouv_p); break; case 'c' : printf("nom> "); scanf("%s", nom); pp = chercher_personne(&carnet, nom); if (pp) afficher_personne(*pp); else printf("Personne inconnue\n"); break; case 'q' : return 0; break; default : printf("Commande inconnue\n"); } do choix = getchar(); while (choix != '\n'); printf("\n"); } return 0; }
< Les fonction d'entrée/sortie | TutoCFrench | Les fonctions de manipulation de fichiers >