1 Avant propos :
En C/C++ typedef permet de créer un nouveau type à partir d’un type existant.
Exemple :
2 Les structures
Contrairement aux tableaux qui regroupent des données de mêmes types, les structures peuvent regrouper des données de types différents.
Exemple : Dans un carnet d’adresse on souhaite accéder aux personnes par leur nom et disposer alors de leur prénom, leur âge, leur sexe.
Le programme ci-dessous montre un exemple de carnet d’adresse.
struct déclare la structure « personne » et ses différents champs.
On crée ensuite des variables de type « personne ». L’accès aux champs se fait avec l’opérateur .
#include <stdio.h>
#include <string.h>
struct personne // declaration de la structure personne {
char nom[10]; // 4 champs de types différents char prenom[10];
int age;
char sexe;
};
int main( ) {
struct personne j1; // j1 est une structure de type personne
strcpy(j1.nom, "dupont"); // accès au champ nom (strcpy recopie la chaine "dupont" dans le tableau nom) strcpy(j1.prenom, "michel");
j1.age=25; // accès au champs age j1.sexe='M';
struct personne j2;
strcpy(j2.nom, "duval");
strcpy(j2.prenom, "penelope");
j2.age=22;
j2.sexe='F';
// la lecture des champs des structures se fait de la même façon
printf("%s %s a %d ans de sexe %c\n",j1.prenom,j1.nom,j1.age,j1.sexe);
printf("%s %s a %d ans de sexe %c\n",j2.prenom,j2.nom,j2.age,j2.sexe);
return 0;
}
#include <stdio.h>
#include <string.h>
typedef unsigned char uc8; // nouveaux types typedef signed char sc8;
int main() {
uc8 a;
sc8 b;
a=200;
b=200;
printf("a=%d b=%d\n",a,b);
return 0;
}
Afin d’éviter d’utiliser le mot struct lors de la déclaration des variables, on peut créer un nouveau type. La déclaration sera alors plus simple.
3 Recopie et passage en paramètre à une fonction
Une structure peut être recopiée et passée en paramètre d’une fonction :
#include <stdio.h>
#include <string.h>
typedef struct // création d'un nouveau type de données {
int heure;
int minute;
int seconde;
char jour[10];
int date;
char mois[10];
int annee;
} temps; // le type s'apelle temps int main( ) {
temps chrono; // chrono est de type temps chrono.heure=10;
chrono.minute=45;
chrono.seconde=24;
strcpy(chrono.jour, "mardi");
chrono.date=14;
strcpy(chrono.mois, "avril");
chrono.annee=2020;
printf("Heure %d:%d:%d\n",chrono.heure,chrono.minute,chrono.seconde);
printf("Date %s %d %s %d\n",chrono.jour,chrono.date,chrono.mois,chrono.annee);
return 0;
}
#include <stdio.h>
#include <string.h>
typedef struct // création d'un nouveau type de données {
int heu;
int min;
int sec;
} temps; // le type s'apelle temps void affiche(temps x)
{
printf("%d:%d:%d\n",x.heu,x.min,x.sec);
}
int main( ) {
temps c1; // c1, c2, c3 sont des structures de type temps temps c2;
temps c3 = {18,23,57}; // initialisation séquentielle c1.heu=10;
c1.min=45;
c1.sec=24;
c2=c1; // recopie
affiche(c1); // passage d'une structure en paramètre d'une fonction affiche(c2);
affiche(c3);
return 0;
}
4 Pointeur sur une structure
Déclarations :
temps chrono ; // chrono est une structure de type temps
temps *p ; // p est un pointeur sur une structure de type temps int *i ; // un pointeur sur un entier
p=&chrono ; // p pointe sur chrono
i=&p.heu ; // un pointeur sur un membre de la structure Accès aux membres de la structure :
(*p).heu=22 ;
Le C dispose de l’opérateur flèche -> qui simplifie la syntaxe, on peut écrire : p->heu=22 ; Exemple :
5 Taille d’une structure :
sizeof retourne naturellement la taille d’une structure, ici 3 entiers codés sur 32bits soit 12 octets.
#include <stdio.h>
#include <string.h>
typedef struct // création d'un nouveau type de données {
int heu;
int min;
int sec;
} temps; // le type s'apelle temps void affiche(temps *x)
{
printf("%d:%d:%d\n",x->heu,x->min,x->sec);
}
int main( ) {
temps c1={10,45,22};
temps *pt; // pt est un pointeur sur une structure de type temps pt=&c1; // pt pointe sur c1
affiche(pt); // passage de la structure par adresse pt->heu=19;
pt->min=54;
pt->sec=31;
affiche(pt);
return 0;
}
#include <stdio.h>
#include <string.h>
typedef struct // création d'un nouveau type de données {
int heu;
int min;
int sec;
} temps; // le type s'apelle temps int main( )
{ int i;
temps c1;;
i=sizeof(c1);
printf("%d\n",i);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
typedef struct // déclaration d'un nouveau type de données t_heure {
int heu;
int min;
int sec;
} t_heure;
typedef struct // déclaration d'un nouveau type de données t_temps {
t_heure heure; //la structure t_temps contient une structure void (*paff)(t_heure *); // et un pointeur sur une fonction
} t_temps;
void affiche(t_heure *x) // affichage d'une structure t_heure {
printf("%02d:%02d:%02d\n",x->heu,x->min,x->sec);
}
void affCh1(t_heure *x) // affichage d'un message puis appel affiche {
printf("Chrono1 -> ");
affiche(x);
}
void affCh2(t_heure *x) {
printf("Chrono2 -> ");
affiche(x);
}
void affDiff(t_heure *x) {
printf("Difference -> ");
affiche(x);
}
// calcule de la différence entre deux heures dans des structures t_heures // Le résulat est renvoyé dans une structure t_heure
t_heure calcDiff(t_heure* t1, t_heure* t2) {
t_heure tcalc;
int sec;
sec=(t1->heu*3600+t1->min*60+t1->sec)-(t2->heu*3600+t2->min*60+t2->sec);
tcalc.heu=sec/3600;
tcalc.min=sec/60-(tcalc.heu)*60;
tcalc.sec=sec-(tcalc.min)*60-(tcalc.heu)*3600;
return tcalc;
} int main() {
t_temps chrono1={{10,0,12}}; // deux variables t_heure
t_temps chrono2={{11,1,15}}; //les {{ indiques que l'initialisation se fait dans une structure intégrée t_temps diff; // diff contient une heure
// initialise les pointeurs de fonctions vers les fonctions d'affichage chrono1.paff=&affCh1;
chrono2.paff=&affCh2;
diff.paff=&affDiff;
// calcul de l'intervalle
diff.heure=calcDiff(&chrono2.heure,&chrono1.heure); // chrono2-chrono1 // affichage personnalisé
chrono1.paff(&chrono1.heure);
chrono2.paff(&chrono2.heure);
diff.paff(&diff.heure);
return 0;
}
6 Allez plus loin, vers les objets du C++
Il est possible de déclarer une structure dans une structure.
Il est possible de déclarer un pointeur sur une fonction dans une structure.
Le programme ci-dessous affiche l’intervalle entre deux moments.
Le type t_temps contient une structure de type t_heure et un pointeur vers une fonction.
Exemple : tracé d’un rectangle
#include <stdio.h>
#include <stdlib.h>
// type structure définissant les coordonnées d'un point typedef struct
{ int x;
int y;
} t_point;
// type structure définissant deux points d'un rectangle typedef struct
{
t_point p1; //point haut gauche t_point p2; //point bas droit } t_rectangle;
void dessineLignePleine(t_rectangle *r) {
int a;
for(a=1; a<r->p1.x; a++) printf(" ");
printf("+");
a++;
for(;a<r->p2.x; a++) printf("-");
printf("+\n");
}
void dessineLigneVide(t_rectangle *r) {
int a;
for(a=1;a<r->p1.x; a++) printf(" ");
printf("|");
a++;
for(;a<r->p2.x; a++) printf(" ");
printf("|\n");
}
void dessine(t_rectangle *r) {
int a,b;
for(a=0; a<(r->p1.y); a++) printf("\n");
dessineLignePleine(r);
b=(r->p1.y)+1;
while(b<r->p2.y) {
dessineLigneVide(r);
b++;
}
dessineLignePleine(r);
}
int main() {
t_rectangle rect= {{5,3},{10,8}};
printf("Rectangle x1=%d y1=%d x2=%d y2=%d",rect.p1.x,rect.p1.y,rect.p2.x,rect.p2.y);
dessine(&rect);
return 0;
}