您发现的行为实际上是C语言的一大弊端。每当您声明带有数组参数的函数时,编译器都会忽略您,并将参数更改为指针。因此,这些声明的行为都类似于第一个声明:
void func(int *a)
void func(int a[])
void func(int a
typedef int array_plz[5];
void func(array_plz a)
在所有四种情况下,a都是指向int的指针。如果将数组传递给func,它将立即衰减为指向其第一个元素的指针。(在64位系统上,64位指针的大小是32位int的两倍,因此sizeof比率返回2。)
此规则的唯一目的是保持与不支持将聚合值作为函数参数传递的历史编译器的向后兼容性。
这并不意味着不可能将数组传递给函数。您可以通过将数组嵌入到struct中来解决这个问题(这基本上是C ++ 11的std :: array的目的):
struct array_rly {
int a[5];
};
void func(struct array_rly a)
{
printf("%zd\n", sizeof(a.a)/sizeof(a.a[0])); /* prints 5 */
}
或通过将指针传递给数组:
void func(const int (*a)[5])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints 5 */
}
如果数组大小不是编译时常量,则可以对C99可变长度数组使用指针数组技术:
void func(int n, const int (*a)[n])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints n */
}