Tout d'abord, quelques standards :
6.7.5.3 Déclarateurs de fonction (y compris les prototypes)
...
7 Une déclaration d'un paramètre comme `` tableau de type '' doit être ajustée en `` pointeur qualifié vers le
type '', où les qualificatifs de type (le cas échéant) sont ceux spécifiés dans [
et ]
de la dérivation de type tableau. Si le mot-clé static
apparaît également dans la dérivation de type tableau [
et ]
de, alors pour chaque appel à la fonction, la valeur de l'argument réel correspondant doit fournir l'accès au premier élément d'un tableau avec au moins autant d'éléments que spécifié par la taille expression.
Donc, en bref, tout paramètre de fonction déclaré comme T a[]
ou T a[N]
est traité comme s'il avait été déclaré T *a
.
Alors, pourquoi les paramètres de tableau sont-ils traités comme s'ils étaient déclarés comme des pointeurs? Voici pourquoi:
6.3.2.1 Lvalues, tableaux et désignateurs de fonction
...
3 Sauf s'il s'agit de l'opérande de l' sizeof
opérateur ou de l' &
opérateur unaire , ou s'il s'agit d' une chaîne littérale utilisée pour initialiser un tableau, une expression de type '' tableau de type ' 'est converti en une expression avec le type' 'pointeur sur le type ' 'qui pointe vers l'élément initial de l'objet tableau et n'est pas une lvalue. Si l'objet tableau a une classe de stockage de registre, le comportement n'est pas défini.
Compte tenu du code suivant:
int main(void)
{
int arr[10];
foo(arr);
...
}
Dans l'appel à foo
, l'expression de tableau arr
n'est pas un opérande de l'un sizeof
ou l' autre &
, donc son type est implicitement converti de "tableau à 10 éléments de int
" en "pointeur vers int
" selon 6.2.3.1/3. Ainsi, foo
recevra une valeur de pointeur, plutôt qu'une valeur de tableau.
En raison de 6.7.5.3/7, vous pouvez écrire foo
comme
void foo(int a[]) // or int a[10]
{
...
}
mais il sera interprété comme
void foo(int *a)
{
...
}
Ainsi, les deux formes sont identiques.
La dernière phrase du 6.7.5.3/7 a été introduite avec C99, et signifie essentiellement que si vous avez une déclaration de paramètre comme
void foo(int a[static 10])
{
...
}
le paramètre réel correspondant à a
doit être un tableau d' au moins 10 éléments.