A partir des types prédéfinis du C (caractères, entiers, flottants),
on peut créer de nouveaux types, appelés types composés, qui
permettent de représenter des ensembles de données organisées.
#define N 10
main()
{
int tab[N];
int i;
...
for (i = 0; i < N; i++)
printf("tab[%d] = %d\n",i,tab[i]);
}
Un tableau correspond en fait à un pointeur vers le premier
élément du tableau. Ce pointeur est constant. Cela implique en
particulier qu'aucune opération globale n'est autorisée sur un
tableau. Notamment, un tableau ne peut pas figurer à gauche d'un
opérateur d'affectation. Par exemple, on ne peut pas écrire ``tab1
= tab2;''. Il faut effectuer l'affectation pour chacun des éléments
du tableau :
#define N 10
main()
{
int tab1[N], tab2[N];
int i;
...
for (i = 0; i < N; i++)
tab1[i] = tab2[i];
}
On peut initialiser un tableau lors de sa déclaration par une liste de
constantes de la façon suivante :
#define N 4
int tab[N] = {1, 2, 3, 4};
main()
{
int i;
for (i = 0; i < N; i++)
printf("tab[%d] = %d\n",i,tab[i]);
}
Si le nombre de données dans la liste d'initialisation est inférieur
à la dimension du tableau, seuls les premiers éléments seront
initialisés. Les autres éléments seront mis à zéro si le tableau est
une variable globale (extérieure à toute fonction) ou une variable
locale de classe de mémorisation static (cf. chapitre 4).\0'. Il faut donc
que le tableau ait au moins un élément de plus que le nombre de
caractères de la chaîne littérale.
#define N 8
char tab[N] = "exemple";
main()
{
int i;
for (i = 0; i < N; i++)
printf("tab[%d] = %c\n",i,tab[i]);
}
Lors d'une initialisation, il est également possible de ne pas
spécifier le nombre d'éléments du tableau. Par défaut, il correspondra
au nombre de constantes de la liste d'initialisation. Ainsi le
programme suivant imprime le nombre de caractères du tableau tab, ici 8.
char tab[] = "exemple";
main()
{
int i;
printf("Nombre de caracteres du tableau = %d\n",sizeof(tab)/sizeof(char));
}
De manière similaire, on peut déclarer un tableau à plusieurs
dimensions. Par exemple, pour un tableau à deux dimensions :
#define M 2
#define N 3
int tab[M][N] = {{1, 2, 3}, {4, 5, 6}};
main()
{
int i, j;
for (i = 0 ; i < M; i++)
{
for (j = 0; j < N; j++)
printf("tab[%d][%d]=%d\n",i,j,tab[i][j]);
}
}
struct modele
{type-1 membre-1;
type-2 membre-2;
...
type-n membre-n;
};
Pour déclarer un objet de type structure correspondant au modèle
précédent, on utilise la syntaxe :
struct modele
{type-1 membre-1;
type-2 membre-2;
...
type-n membre-n;
}objet;
On accède aux différents membres d'une structure grâce à l'opérateur
membre de structure, noté
``.''. Le i-ème membre de objet est désigné par
l'expression
#include <math.h>
struct complexe
{
double reelle;
double imaginaire;
};
main()
{
struct complexe z;
double norme;
...
norme = sqrt(z.reelle * z.reelle + z.imaginaire * z.imaginaire);
printf("norme de (%f + i %f) = %f \n",z.reelle,z.imaginaire,norme);
}
Les règles d'initialisation d'une structure lors de sa déclaration sont les
mêmes que pour les tableaux. On écrit par exemple :
...
main()
{
struct complexe z1, z2;
...
z2 = z1;
}
struct registre
{
unsigned int actif : 1;
unsigned int valeur : 31;
};
possède deux membres, actif qui est codé sur un seul bit, et
valeur qui est codé sur 31 bits. Tout objet de type struct registre
est donc codé sur 32 bits. Toutefois, l'ordre dans lequel les champs
sont placés à l'intérieur de ce mot de 32 bits dépend de
l'implémentation. &.
union jour
{
char lettre;
int numero;
};
main()
{
union jour hier, demain;
hier.lettre = 'J';
printf("hier = %c\n",hier.lettre);
hier.numero = 4;
demain.numero = (hier.numero + 2) % 7;
printf("demain = %d\n",demain.numero);
}
Les unions peuvent être utiles lorsqu'on a besoin de voir un objet
sous des types différents (mais en général de même taille).
Par exemple, le programme suivant permet de manipuler en même temps
les deux champs de type unsigned int d'une structure en les
identifiant à un objet de type unsigned long (en supposant que
la taille d'un entier long est deux fois celle d'un int).
struct coordonnees
{
unsigned int x;
unsigned int y;
};
union point
{
struct coordonnees coord;
unsigned long mot;
};
main()
{
union point p1, p2, p3;
p1.coord.x = 0xf;
p1.coord.y = 0x1;
p2.coord.x = 0x8;
p2.coord.y = 0x8;
p3.mot = p1.mot ^ p2.mot;
printf("p3.coord.x = %x \t p3.coord.y = %x\n", p3.coord.x, p3.coord.y);
}
main()
{
enum booleen {faux, vrai};
enum booleen b;
b = vrai;
printf("b = %d\n",b);
}
On peut modifier le codage par défaut des valeurs de la liste lors de
la déclaration du type énuméré, par exemple :
struct complexe
{
double reelle;
double imaginaire;
};
typedef struct complexe complexe;
main()
{
complexe z;
...
}
This document was translated from LATEX by HEVEA.