Znalezione zachowanie jest w rzeczywistości wielką brodawką w języku C. Za każdym razem, gdy deklarujesz funkcję, która przyjmuje parametr tablicy, kompilator ignoruje Cię i zmienia parametr na wskaźnik. Zatem wszystkie te deklaracje zachowują się jak pierwsza:
void func(int *a)
void func(int a[])
void func(int a
typedef int array_plz[5];
void func(array_plz a)
a będzie wskaźnikiem do int we wszystkich czterech przypadkach. Jeśli przekażesz tablicę do func, natychmiast rozpadnie się ona na wskaźnik do jej pierwszego elementu. (W systemie 64-bitowym 64-bitowy wskaźnik jest dwa razy większy niż 32-bitowy int, więc współczynnik sizeof zwraca 2.)
Jedynym celem tej reguły jest zachowanie wstecznej kompatybilności z kompilatorami historycznymi, które nie obsługiwały przekazywania wartości zagregowanych jako argumentów funkcji.
Nie oznacza to, że niemożliwe jest przekazanie tablicy do funkcji. Możesz obejść tę brodawkę, osadzając tablicę w strukturze (jest to w zasadzie celem std :: array w C ++ 11):
struct array_rly {
int a[5];
};
void func(struct array_rly a)
{
printf("%zd\n", sizeof(a.a)/sizeof(a.a[0])); /* prints 5 */
}
lub przekazując wskaźnik do tablicy:
void func(const int (*a)[5])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints 5 */
}
W przypadku, gdy rozmiar tablicy nie jest stałą czasu kompilacji, możesz użyć techniki wskaźnika do tablicy z tablicami o zmiennej długości C99:
void func(int n, const int (*a)[n])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints n */
}