为什么一个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 ++参考