Tableaux
Un tableau consiste en des cases contigus dans la mémoire.
int A[4];
On peut initialiser un tableau directement comme ça :
int A[4] = {1, 2, 3, 5};
C'est le type qui détermine le nombre d'octets d'une case mémoire :
char A[4];
Ils peuvent être multidimensionels.
int A[4][3];
Tableau de taille non connue à la compilation
Depuis C99, on peut définir des tableaux de taille non connue à l'avance, à la compilation.
void f(int n) {
int A[n+5];
...
}
Attention cependant, cette fonctionnalité n'est pas autorisée en C++. La raison : une incompatibilité avec les templates car A[1]
, A[2]
, A[3]
, A[4]
, etc. sont tous des types différents.
Tableaux globaux
Les tableaux globaux doivent avoir une taille fixée à la compilation. Ils sont stockés dans le segment de données.
Tableaux locaux à une fonction
Ils sont stockés dans la pile pas dans le tas.
Tableau 1D en paramètre
Quand on passe un tableau en paramètres, on donne un pointeur, c'est-à-dire l'adresse mémoire du tableau. Autrement dit, quand on empile le paramètre, on empile juste son adresse, et pas touuuuuuuuuuut le tableau.
void f(char A[300000]) {
...
}
En particulier, si on fait :
void f(char A[300000]) {
printf("%d\n", sizeof(A));
}
Ca imprime 8 et pas 300000.
Ces trois signatures sont équivalentes :
void f(char p[3]);
void f(char p[]);
void f(char* p);
Tableau 2D en paramètre
On peut passer un tableau 2D en paramètre.
void f(char p[4][3])
Par contre, ce n'est pas équivalent à
void f(char p[])
void f(char* p)
Forcément, vu que l'on a pas l'information sur la taille.
On ne peut pas non plus écrire :
void f(char p[][])
car la machine ne sait pas comment interpréter le tableau 2D.
Par contre, on peut omettre la taille selon la première coordonnée et écrire :
void f(char p[][3])
En effet, on a l'information suffisante dans le corps de la fonction pour savoir comment utiliser p
, même si on ne connaît la borne pour le premier indice. Mais c'est à l'humain de faire attention.
Impossible de renvoyer un tableau
int[] createArrayButNotPossible()
{
int A[3] = {1, 2, 5};
return A;
}
Le code suivant compile... mais renvoie une adresse vers une zone mémoire qui n'est plus allouée :
int* createArrayButNotPossible()
{
int A[3] = {1, 2, 5};
return A;
}
Aller plus loin
-
For 2D arrays: see here
-
Peut-on allouer un tableau dynamiquement dans le tas qui est multidimensionel ?