Exood4 Studio - Video Game Development, Toulouse (France)
Exood4 Studios Exood4 Tutorials

   
L a n g a g e   C

L e s   t a b l e a u x






La définition


 Si T est un type, on peut construire un objet de type tableau de T par :

 T objet [expression_constante] (chaque élément du tableau est de type T)

int tab[10]; /* tableau de 10 entiers */

 Cependant, on ne peut pas définir de tableaux de fonctions : les tableaux peuvent contenir des pointeurs de fonctions, mais pas les fonctions elles-mêmes.

 Les tableaux à plusieurs dimensions se déclarent de la manière suivante :

int damier[8][8]; /* tableau à 2 dimensions */
float cube[10][10][10];   /* tableau à 3 dimensions */





Les éléments


 Les éléments d'un tableau ont un indice compris entre 0 et (nombre d'éléments - 1).

int tab[5]; /* éléments : tab[0], tab[1] ... tab[4] */

 L'ordre en mémoire des éléments d'un tableau à plusieurs dimensions est le suivant :

float mat[2][2]; /* mat [0][0], mat[0][1], mat[1][0] et mat[1][1] */


 Pour "balayer" les éléments d'un tableau séquentiellement, on fait varier les indices en commençant par la droite :


Exemple :

unsigned int ecran[600][800]; /* écran de taille 800 (largeur) x 600 (hauteur) */

ecran[y][x] est équivalent à *(ecran + y*800 + x)


L'initialisation


 Un tableau peut être initialisé lors de sa définition avec des valeurs constantes :

int tab[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
char message[6] = { 'e' , 'r', 'r', 'e', 'u', 'r' };


 On peut ne pas mentionner le nombre d'éléments lorsqu'un tableau est initialisé lors de sa définition, celui-ci sera alors égal au nombre de valeurs fournies :

int tab[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; /* équivalent à la définition précédente */
char message[] = { 'e' , 'r', 'r', 'e', 'u', 'r' };   /* équivalent à la définition précédente */

 Un nombre de constantes supérieures à la taille du tableau provoque une erreur de compilation. Par contre si ce nombre est inférieur, les éléments restants sont initialisés à 0 :

int tab[5] = { 1, 2, 3 }; /* équivalent à { 1, 2, 3, 0, 0 } */


Précisions sur la définition


 En règle générale, le nombre d'éléments d'un tableau peut être omis s'il n'est pas nécessaire au compilateur c'est à dire si :
  • le tableau juste déclaré, alors qu'il est déjà défini : extern int tab[];

  • le tableau est un paramètre de fonction : void f (int tab[]);

  • le tableau est initialisé lors de sa définition
 Par conséquent, pour un tableau multidimensionnel, afin que le compilateur puisse déterminer la fonction d'indexation, seule la première dimension peut être omise.

extern int matrice[][10];

void f (int matrice[][10]);


Tableaux et pointeurs


 Si tab est un tableau sizeof(tab) donne la taille du tableau (nombre d'éléments * taille d'un élément). La référence &tab donne l'adresse du tableau.

 Hormis ces deux cas (calcul de la taille et de la référence), dans toute autre expression, tab est converti en un pointeur sur le premier élément du tableau (&tab[0]). Aussi nous pouvons exprimer les indices en terme d'arithmétique de pointeurs :

 tab[i] est équivalent à *(tab+i), de même tab[1][2] est équivalent à *(*(tab+1)+2) ...

 On peut ainsi utiliser les pointeurs pour disposer de tableaux dynamiques : créés avec malloc ou calloc, leur taille peut être ajustée avec realloc et ils sont détruits avec free :

int *tab;

tab = malloc (nb * sizeof(int));
for (i = 0; i < nb; i++)
scanf ("%d", &tab[i]);


Tableaux et fonctions


 Lorsqu'un tableau est passé en paramètre à une fonction, conformément à la règle ci-dessus, l'expression f(tab) est convertie en f(&tab[0]). Par conséquent, bien que le seul mécanisme en C soit le passage par valeur, et qu'effectivement &tab[0] soit recopié localement, le tableau se retrouve transmis par adresse, et toute modification de ses éléments se répercute dans la fonction appelante.

 Autre conséquence : un tableau peut être passé en paramètre à une fonction qui attend un pointeur, et réciproquement. Par exemple si tab est déclaré par :

int tab[10];

 l'appel f(tab) est valide pour une fonction f déclarée ainsi :

void f (int [10]);
void f (int []);
void f (int *);

 Une fonction ne peut pas retourner un tableau, mais seulement l'adresse de son premier élément, ou l'adresse du tableau lui-même.


Opérations sur les tableaux


 L'affectation entre tableaux et la comparaison de deux tableaux n'existent pas en C.

 tab1 = tab2 provoque une erreur de compilation, puisque tab1, converti en l'adresse de son premier élément, est une constante. La recopie doit être effectuée soit élément par élément, soit avec une fonction de copie de blocs mémoire comme memcpy.

memcpy (tab1, tab2, sizeof(tab2));

 Par contre tab1 == tab2 est valide, mais il s'agit d'un test sur l'égalité entre deux pointeurs.

void f (int tab2[])
{
 if (tab1 == tab2) erreur();
 ...
}

 Pour comparer le contenu de deux tableaux, soit on compare les éléments les uns après les autres, soit on utilise une fonction de comparaison de blocs mémoire comme memcmp :

memcmp (tab1, tab2, nombre_elements_a_comparer);



  Retour en haut de page Page suivante