21

谁能告诉我为什么我应该费心在函数头中指定 C 数组参数的大小?例如:

void foo (int iz[6]) { iz[42] = 43; }

和:

int is[2] = {1,2,3};

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

4

4 回答 4

20

谁能告诉我为什么我应该费心在函数头中指定 C 数组参数的大小?例如:

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

海事组织,你不应该。当您尝试将数组传递给函数时,真正传递的是指向数组开头的指针。由于函数接收到的是一个指针,所以最好把它写成明确的:

void foo(char const *sz)

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

void foo(char const *sz, size_t size)
于 2011-03-03T22:16:04.557 回答
18

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

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

void foo (int iz[static 6])

它向编译器承诺该数组将具有至少 6 个元素,这意味着编译器将能够使用该假设优化该代码。此外,如果您真的想采用上述约定,那么明确声明数组参数大小更有意义static,因为该语言明确定义了此构造的语义。

我不清楚“我们得到一个有用的错误”是什么意思。编码

int is[2] = {1,2,3};
is[42] = 42;

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

于 2014-10-16T17:41:44.537 回答
8

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

于 2011-03-03T22:11:28.073 回答
0

当您想告诉客户端代码它必须传递一个定义大小的数组时,这是一个有用的注释,即:

void foo(const char bar[5]);
/* It is expected that foo function receives an array of size 5 */

然而,文档不会在代码检查中取代:

void foo(const char bar[5])
{
    if (!bar) error();
    if (strlen(bar) != 4) error();
    /* ... */
}
于 2014-10-16T17:37:19.277 回答