您发现的行为实际上是 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。)
此规则的唯一目的是保持与不支持将聚合值作为函数参数传递的历史编译器的向后兼容性。
这并不意味着不可能将数组传递给函数。您可以通过将数组嵌入到结构中来解决这个问题(这基本上是 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 */
}