2

我有一个小问题:我可以计算向量的长度,但前提是向量是在同一个函数中定义的。当我尝试将向量传递给另一个函数时,它返回错误的输出,我不明白为什么。

#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。

4

3 回答 3

7

这是因为数组在传递给函数时会衰减为指向其第一个元素的指针。

没有与数组关联的长度的运行时存储,所以这不起作用。基本上,对于函数参数,类型int a[]等价于int *a,即它只是一个指针。

当您需要将数组传递给函数时,最好总是简单地传递一个长度,并且您永远不能拥有像您的len(). 当然,如果您自己将长度存储在指向的数据中,则例外情况,就像字符串对终止符所做的那样。

作为一个风格点,这段代码在main()

printf("%d\n", sizeof(a)/sizeof(int));

在我看来,最好写成:

printf("%zu\n", sizeof a / sizeof *a);

具有以下值得注意的变化:

  • sizeofhas 类型的结果size_t,它不是int. 它由格式说明符正确打印%zu
  • 请注意,这sizeof不是函数,因此在大多数情况下不需要括号。
  • 更喜欢引用变量,而不是重复可能与变量关联或不关联的类型名称。意思是“指向sizeof *a的值的大小”。a
  • 另请注意,根据C 的运算符优先级规则sizeof绑定比 更紧密/,因此表达式的真正含义是(sizeof a) / (sizeof *a),这是期望的结果。
于 2013-02-01T10:27:56.090 回答
2

您的len函数将一个未指定大小的数组作为参数,在这种情况下,它被视为只是一个指针类型(在您的情况下为int指针)。在您的特定平台上,指针的大小与 a 的大小相同, 1 也是int如此sizeof(vec)/sizeof(int)

如果您明确指定数组参数的长度,那么您的大小计算将按预期运行——但您的函数将只采用该长度的数组参数。

另请参阅:作为函数参数的 C++ 数组

于 2013-02-01T10:28:29.900 回答
1

因为int len(int vec[])实际上是一个int len(int *vec). len变量内部vec被视为一个指针,因此sizeof vec返回保存地址所需的字节数。

请注意,这sizeof是一个运算符,而不是一个函数。这意味着返回的值sizeof是在编译时计算的。

于 2013-02-01T10:32:59.863 回答