On touche là une question subtile du C, et ma réponse méritera probablement d'être étoffée, mais allons y :
Les tableaux sont en C l'unique manière de garantir qu'une collection de variables sera stocké dans un espace contigu en mémoire.
Il faut rappeler que l'opérateur d'indexation de tableau en C ("[]") est un sucre syntaxique qui masque un déréférencement de pointeur ainsi que de l’arithmétique sur pointeur.
Pour illustrer, les lignes 1 et 2 suivantes sont identiques :
int int_array[10];
int *p = array;
int_array[7] = 1; // #1
*(p+7) = 1; // #2
Ces lignes équivalentes sont un sucre syntaxique sur ce que le compilateur fait réellement, c'est à dire :
*((int *)(((char *) p) + (7 * sizeof(int)))) = 1; // #3
Ceci s'obscurcit encore car le nom d'un tableau peut être converti en l'adresse du pointeur du premier élément. L'expression suivante renvoie donc vrai :
int_array == &(int_array[0])
De là, on peut aboutir au fait qu'un pointeur peut être traitée comme étant la première case d'un tableau. Et c'est pour ça que l'on entretient la confusion que pointeur == tableau.