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

⚠ Le code suivant ne compile pas.. le type `int[]` n'existe pas :
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 ?