我有一个小问题:我可以计算向量的长度,但前提是向量是在同一个函数中定义的。当我尝试将向量传递给另一个函数时,它返回错误的输出,我不明白为什么。
#include <stdio.h>
int len(int vec[]);
main()
{
int a[6];
printf("%d\n", sizeof(a)/sizeof(int));
printf("%d\n", len(a));
return 0;
}
len(int vec[])
{
return sizeof(vec)/sizeof(int);
}
输出是:
6
1
为什么函数len()
不起作用?它应该返回6而不是1。
答案 0 :(得分:7)
这是因为当传递给函数时,数组将衰减成指向其第一个元素的指针。
没有与数组关联的长度的运行时存储,因此这不起作用。基本上对于函数参数,int a[]
等类型与int *a
等效,即它只是一个指针。
当你需要将数组传递给函数时,最好总是传递一个长度,而你永远不能拥有像len()
这样的函数。当然,例外情况是您将自己的长度存储在指向的数据中,就像字符串与终结符一样。
作为一个风格点,main()
中的代码:
printf("%d\n", sizeof(a)/sizeof(int));
在我看来,写得更好:
printf("%zu\n", sizeof a / sizeof *a);
具有以下值得注意的变化:
sizeof
的结果类型为size_t
,而不是int
。它由格式说明符%zu
正确打印。sizeof
不是函数,因此在大多数情况下不需要括号。sizeof *a
表示“a
指向的值的大小。”sizeof
比/
更紧密,因此表达式实际上意味着(sizeof a) / (sizeof *a)
,这是期望的结果。答案 1 :(得分:2)
您的len
函数将一个未指定大小的数组作为参数,在这种情况下,它仅被视为指针类型(在您的情况下,int
指针)。在您的特定平台上,指针的大小与int
的大小相同,因此sizeof(vec)/sizeof(int)
为1。
如果明确指定数组参数的长度,那么您的大小计算将按预期运行 - 但是您的函数将只接受完全相同长度的数组参数。
答案 2 :(得分:1)
因为int len(int vec[])
实际上是int len(int *vec)
。在len
内部,变量vec
被视为指针,因此sizeof vec
返回保存地址所需的字节数。
请注意sizeof
是一个运算符,而不是一个函数。这意味着sizeof
所返回的值是在编译时计算的。