为啥将 C-Array 传递给函数时 sizeof() 值错误? [复制]
Posted
技术标签:
【中文标题】为啥将 C-Array 传递给函数时 sizeof() 值错误? [复制]【英文标题】:Why does a C-Array have a wrong sizeof() value when it's passed to a function? [duplicate]为什么将 C-Array 传递给函数时 sizeof() 值错误? [复制] 【发布时间】:2011-02-26 09:05:01 【问题描述】:完整示例:
#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 给了我正确的值。对函数中完全相同的数组执行完全相同的操作会产生奇怪的结果。少了一个元素。为什么?
【问题讨论】:
【参考方案1】:因为在 C、C++ 和 Objective-C 中,函数实际上不能有数组参数。它们只能具有看起来像数组参数的参数,但它们不是。在你的例子中,
void test(int arr[])
编译器看到“有一个参数看起来像一个 int 数组”,并将该参数替换为“指向 int 的指针”。所以你写的函数绝对百分百与
void test (int* arr)
因此,在函数 sizeof (arr) 内部会给你一个“指向 int 的指针”的大小。
【讨论】:
【参考方案2】:此外,了解sizeof
在编译时 进行评估也很重要。既然是这种情况,根据传入的内容来期望 test()
中的不同输出是没有意义的。sizeof
计算是在编译函数时完成的。
【讨论】:
【参考方案3】:当您将数组传递给 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])
技巧不适用于动态分配的数组,仅适用于堆栈上分配的数组。
【讨论】:
【参考方案4】:因为数组在作为函数参数传递时是指向指针的 decayed,所以 sizeof
分别为 32 位和 64 位平台提供 4 和 8。
【讨论】:
【参考方案5】:因为 sizeof() 不会告诉你 C 中数组的大小。它做的事情完全不同。
sizeof C++ reference
【讨论】:
如果你仔细看过这个例子,你会发现我没有使用 sizeof 来直接获取数组中的元素个数... sizeof 应该告诉我有多少内存为数组保留......实际上,当元素的大小已知时,它应该与其中的元素数量相匹配。还是我错过了什么? 我的立场是正确的。但如上所述,要小心指针。他们告诉你它们的大小,而不是你指向的类型的大小。【参考方案6】:因为,当它被传递时,实际上只有指向数组的指针被传递。
The C Programming FAQ 也回答了您的问题。问题 6.21。
【讨论】:
要挑剔:它是指向传递的数组的第一个元素的指针。值相同,但类型不同。以上是关于为啥将 C-Array 传递给函数时 sizeof() 值错误? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
为啥通过 ParamArray 将数组元素传递给函数时,varpointer 会到达函数中?