为什么我要在函数头中声明C数组参数的大小?

use*_*370 18 c arrays function-parameter

任何人都可以告诉我为什么我应该在函数头中指定C数组参数的大小?例如:

void foo (int iz[6]) { iz[42] = 43; }
Run Code Online (Sandbox Code Playgroud)

附:

int is[2] = {1,2,3};
Run Code Online (Sandbox Code Playgroud)

我们得到一个有用的错误.也许它有助于评论/文档?

Jer*_*fin 16

任何人都可以告诉我为什么我应该在函数头中指定C数组参数的大小?例如:

void foo(const char sz [6]){sz [42] = 43; }

IMO,你不应该.当您尝试将数组传递给函数时,实际传递的是指向数组开头的指针.由于函数接收的是指针,因此最好将其写为显式:

void foo(char const *sz)
Run Code Online (Sandbox Code Playgroud)

然后,由于现在很清楚该函数没有给出大小的线索,所以将其添加为单独的参数:

void foo(char const *sz, size_t size)
Run Code Online (Sandbox Code Playgroud)

  • 同意.评论不太有用.开发人员可以修改代码以处理长度为9的数组,比如说,并且意外地将6保留在原位. (3认同)
  • @ user643722:如果您的问题是开发人员可以修改代码以使注释不正确,那么无法更新注释,那么您的问题就出现在每个评论中.这似乎不足以说服人们停止写作. (3认同)
  • “你不应该。” 我完全同意。对我来说,一个以 `void foo (int iz[6])` 开头的函数正在隐式地传达(给下一个程序员,而不是编译器)它的实现以某种方式强制执行大小 6。我们遇到了一些遗留代码超出其缓冲区的奇怪问题。`myfunc(char buffer[size])` 中的 `size` 具有欺骗性(或者非 C 编码人员不应该弄乱旧的东西)。 (2认同)

AnT*_*AnT 12

这样做的唯一有意义的原因是出于文档目的 - 告诉未来的用户,函数期望接收至少那么多元素的数组.但即便如此,这也是一个常规问题 - 您必须提前与其他用户达成一致意见.语言(编译器)无论如何都会忽略该大小.您的函数声明等同于void foo(int iz[])void foo(int *iz).

使编译器有意义的唯一方法是将其声明为

void foo (int iz[static 6])
Run Code Online (Sandbox Code Playgroud)

作为对编译器的承诺,该数组将具有至少6个元素,这意味着编译器将能够使用该假设来优化该代码.此外,如果您真的想采用上面提到的约定,那么static具体地声明数组参数大小更有意义,因为语言显式定义了此构造的语义.

您对"我们得到一个有用的错误"的意思并不清楚.代码

int is[2] = {1,2,3};
is[42] = 42;
Run Code Online (Sandbox Code Playgroud)

不包含任何约束违规.它会产生未定义的行为,但在编译期间不需要生成诊断消息.换句话说,不,我们没有得到任何"有用的错误".

  • `void foo (int iz[static 6])` 中的 `static` 是 C99、C11 的创新吗? (2认同)

nmi*_*els 7

这是一个评论.数组被降级为函数参数中的指针.但是,即使编译器没有读取它们,注释仍然很有用.