Najpierw kilka standardowych :
6.7.5.3 Deklaratory funkcji (w tym prototypy)
...
7 Deklaracja parametru jako `` tablica typu '' powinna być dostosowana do `` kwalifikowanego wskaźnika do
typu '', gdzie kwalifikatorami typu (jeśli istnieją) są te określone w obrębie [i ]wyprowadzenia typu tablicy. Jeśli słowo kluczowe staticwystępuje również w [i ]w wyprowadzeniu typu tablicy, to dla każdego wywołania funkcji wartość odpowiedniego rzeczywistego argumentu zapewnia dostęp do pierwszego elementu tablicy zawierającego co najmniej tyle elementów, ile określono w rozmiarze wyrażenie.
Krótko mówiąc, każdy parametr funkcji zadeklarowany jako T a[]lub T a[N]jest traktowany tak, jakby był zadeklarowany T *a.
Dlaczego więc parametry tablicowe są traktowane tak, jakby były zadeklarowane jako wskaźniki? Dlatego:
6.3.2.1 Wartość lvalues, tablice i desygnatory funkcji
...
3 Z wyjątkiem sytuacji, gdy jest to operand sizeofoperatora lub operator jednoargumentowy &lub literał łańcuchowy używany do inicjalizacji tablicy, wyrażenie o typie `` tablica typu '' 'jest konwertowane na wyrażenie z typem' 'wskaźnik do typu ' ', które wskazuje na początkowy element obiektu tablicy i nie jest lwartością. Jeśli obiekt tablicy ma klasę pamięci rejestru, zachowanie jest niezdefiniowane.
Biorąc pod uwagę następujący kod:
int main(void)
{
int arr[10];
foo(arr);
...
}
W wywołaniu do foo, wyrażenie tablicowe arrnie jest operandem ani sizeoflub &, więc jego typ jest niejawnie konwertowany z „10-elementowej tablicy int” na „wskaźnik do int” zgodnie z 6.2.3.1/3. W ten sposób foootrzyma wartość wskaźnika, a nie wartość tablicy.
Z powodu 6.7.5.3/7 możesz pisać foojako
void foo(int a[]) // or int a[10]
{
...
}
ale będzie to interpretowane jako
void foo(int *a)
{
...
}
Zatem te dwie formy są identyczne.
Ostatnie zdanie w 6.7.5.3/7 zostało wprowadzone za pomocą C99 i zasadniczo oznacza, że jeśli masz deklarację parametru, taką jak
void foo(int a[static 10])
{
...
}
rzeczywisty parametr odpowiadający amusi być tablicą zawierającą co najmniej 10 elementów.