Das Verhalten, das Sie gefunden haben, ist tatsächlich eine große Warze in der C-Sprache. Immer wenn Sie eine Funktion deklarieren, die einen Array-Parameter akzeptiert, ignoriert der Compiler Sie und ändert den Parameter in einen Zeiger. Diese Erklärungen verhalten sich also alle wie die erste:
void func(int *a)
void func(int a[])
void func(int a
typedef int array_plz[5];
void func(array_plz a)
a ist in allen vier Fällen ein Zeiger auf int. Wenn Sie ein Array an func übergeben, zerfällt es sofort in einen Zeiger auf sein erstes Element. (Auf einem 64-Bit-System ist ein 64-Bit-Zeiger doppelt so groß wie ein 32-Bit-Int, sodass Ihre Größe des Verhältnisses 2 zurückgibt.)
Der einzige Zweck dieser Regel besteht darin, die Abwärtskompatibilität mit historischen Compilern aufrechtzuerhalten, die die Übergabe von Aggregatwerten als Funktionsargumente nicht unterstützt haben.
Dies bedeutet nicht, dass es unmöglich ist, ein Array an eine Funktion zu übergeben. Sie können diese Warze umgehen, indem Sie das Array in eine Struktur einbetten (dies ist im Grunde der Zweck des std :: -Arrays von 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 */
}
oder indem Sie einen Zeiger auf das Array übergeben:
void func(const int (*a)[5])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints 5 */
}
Falls die Arraygröße keine Konstante zur Kompilierungszeit ist, können Sie die Zeiger-zu-Array-Technik mit C99-Arrays variabler Länge verwenden:
void func(int n, const int (*a)[n])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints n */
}