Programmation en C :

11. Types élaborés

codecommentaire
/* prog11a.c */
#include <stdio.h>

enum booleen {Faux, Vrai};
enum booleen b;

typedef enum {
  Lundi,Mardi,Mercredi,Jeudi,
  Vendredi,Samedi,Dimanche
  } jour;

jour j;

char* journom[7]={
  "Lundi","Mardi","Mercredi","Jeudi",
  "Vendredi","Samedi","Dimanche"
  };

void main() {
  b=Vrai;
  if (b==Vrai) printf("%d est vrai\n",b);
  else printf("faux\n");
  j=Jeudi;
  printf("code de %s : %d",journom[j],j);
}
enum permet de définir des types symboliques associés à des entiers naturels : Faux=0, Vrai=1 ; Lundi=0, Mardi=1, Mercredi=2, etc.
Remarque. C'est ainsi que fonctionnent les surcouches de C qui ajoutent un type booléen.

typedef permet de donner un nom à un type (le nom du type est à la fin de l'instruction).
N.B. On doit ici conserver le nom complet du type enum booleen qui n'a pas utilisé typedef.

Remarque. On ne verra pas le type union qu'on peut considérer comme obsolète.
/* prog11b.c */
#include <stdio.h>
#include <string.h>

struct individu {
  char nom[20];
  char prenom[20];
  int age;
};

struct individu x;

typedef struct {
  char nom[20];
  char prenom[20];
  int dossier;
  } T_etudiant;

T_etudiant e;

void main() {
strcpy(x.nom,"DURAND");
strcpy(x.prenom,"Martin");
x.age=20;
printf("x.nom=\"%s\"\n",x.nom);
printf("x.prenom=\"%s\"\n",x.prenom);
printf("x.age=%d ans\n\n",x.age);

strcpy(e.nom,"DUPONT");
strcpy(e.prenom,"Martine");
e.dossier=804255;
printf("e.nom=\"%s\"\n",e.nom);
printf("e.prenom=\"%s\"\n",e.prenom);
printf("e.dossier=%d\n",e.dossier);
}
struct permet de créer des types structurés, càd regroupant plusieurs champs.

L'usage de typedef est similaire à ce qui précède (type struct individu, type T_etudiant).
N.B. Préfixer le nom d'un type par T_ est un usage courant en C où les majuscules sont plutôt réservées aux constantes.

L'accès à chaque champ d'une variable structurée se fait à l'aide du caractère point (opérateur d'accès).
/* prog11c.c */
#include <string.h>

typedef struct {
  int jour;
  int mois;
  int annee;
  } T_date;

typedef struct {
  char nom[20];
  char prenom[20];
  int dossier;
  T_date naissance;
  } T_etudiant;

T_etudiant e;

void main() {
strcpy(e.nom,"DUPONT");
strcpy(e.prenom,"Martine");
e.dossier=804255;
(e.naissance).jour=31;
(e.naissance).mois=12;
(e.naissance).annee=1899;
}
Un type structuré peut contenir un autre type.
N.B. La déclaration des types doit se faire dans le bon ordre...
/* prog11d.c */
#include <stdio.h>
#include <string.h>

typedef struct {
  char nom[20];
  char prenom[20];
  int dossier;
  } T_etudiant;

T_etudiant e;

int numerodossier(T_etudiant e) {
  return e.dossier;
}

T_etudiant definir1() {
  T_etudiant t;
  strcpy(t.nom,"DUPONT");
  strcpy(t.prenom,"Martine");
  t.dossier=804255;
  return t;
}

void definir2(T_etudiant *e) {
  strcpy((*e).nom,"DUPONT");
  strcpy((*e).prenom,"Martine");
  (*e).dossier=804255;
}

void main() {
  e=definir1();
  definir2(&e);
}
Un type élaboré peut être en paramètre et en retour d'un fonction. On peut aussi passer en paramètre l'adresse d'une variable de type élaboré pour modifier sa valeur par effet de bord.

N.B. (*e). peut s'écrire aussi e-> :
  strcpy(e->nom,"DUPONT");
  strcpy(e->prenom,"Martine");
  (e->dossier=804255;