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

时间:2010-06-01 13:55:11

标签: c arrays function 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给出了正确的值。在函数中完全相同的数组上执行完全相同的操作会产生奇怪的结果。缺少一个元素。为什么呢?

6 个答案:

答案 0 :(得分:42)

当您将数组传递给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])技巧不适用于动态分配的数组,只能在堆栈上分配一个数组。

答案 1 :(得分:13)

因为当作为函数参数传递时,数组对于指针是decayed,所以sizeof分别为32位和64位平台提供4和8。

答案 2 :(得分:6)

此外,了解{strong}编译时评估sizeof非常重要。既然如此,根据传入的内容,期望test()中的不同输出是没有意义的。sizeof计算是在编译函数时完成的。

答案 3 :(得分:3)

因为,当它被传递时,实际上只传递了指向数组的指针。

您的问题也在The C Programming FAQ得到解答。问题6.21。

答案 4 :(得分:2)

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

void test(int arr[])

编译器看到&#34;有一个看起来像int&#34;的数组的参数,它用&#34;指向int&#34;的指针替换该参数。所以你写的函数绝对百分百,与

相同
void test (int* arr)

因此,在函数sizeof(arr)中将给出一个&#34;指向int&#34;的指针的大小。

答案 5 :(得分:0)

因为sizeof()没有告诉你C中数组的大小。它做了一些完全不同的事情。

sizeof C++ reference