为什么一个C数组在传递给一个函数时有一个错误的sizeof()值?

完整的例子:

#include <stdio.h> void test(int arr[]) { int arrSize = (int)(sizeof(arr) / sizeof(arr[0])); printf("%d\n", arrSize); // 2 (wrong?!) } int main (int argc, const char * argv[]) { int point[3] = {50, 30, 12}; int arrSize = (int)(sizeof(point) / sizeof(point[0])); printf("%d\n", arrSize); // 3 (correct :-) ) test(point); return 0; } 

在传递给函数之前,sizeof给了我正确的值。 在函数完全相同的数组上做同样的事情给出奇怪的结果。 有一个元素缺失。 为什么?

当你将一个数组传递给C中的一个函数时,这个数组会衰变成一个指向它的第一个元素的指针。 当您在参数上使用sizeof时,您将获取指针的大小,而不是数组本身。

如果你需要函数来知道数组的大小,你应该把它作为一个单独的参数传递给它:

 void test(int arr[], size_t elems) { /* ... */ } int main(int argc, const char * argv[]) { int point[3] = {50, 30, 12}; /* ... */ test(point, sizeof(point)/sizeof(point[0])); /* ... */ } 

另外请注意,出于类似的原因(取指针的sizeof ), sizeof(point)/sizeof(point[0])技巧对于动态分配的数组不起作用,只有在堆栈上分配一个数组。

因为数组在作为函数参数传递时会衰减为指针,所以sizeof分别为32和64位平台提供了4和8。

此外,理解sizeof是在编译时进行评估是很重要的。 既然如此,那么根据传入的内容,在test()输出不同的输出是没有意义的。计算的sizeof是在编译函数时完成的。

因为,当它通过时,只有指向数组的指针实际上正在被传递。

您的问题也在C编程常见问题解答中得到解答 。 问题6.21。

因为在C,C ++和Objective-C中,函数实际上不能有数组参数。 他们只能有看起来像数组参数的参数,但它们不是 。 在你的例子中,

 void test(int arr[]) 

编译器看到“有一个看起来像int数组的参数”,并用“指向int的”指针替换该参数。 所以你写的功能绝对是百分百的,完全相同

 void test (int* arr) 

因此,函数里面的sizeof(arr)会给你一个“指向int的指针”的大小。

因为sizeof()不会告诉你C中数组的大小,它完全不同。

sizeof C ++参考