关于C#:在C99的for循环体之外声明计数器有什么好处吗?

Is there any benefit to declaring the counter outside of the for loop body in C99?

我对 C 很熟悉,最近决定学习 C。我正在学习的教程中经常写这样的 for 循环:

1
2
3
4
5
6
int i;

for (i = 0; i < 5; i++)
{
    printf("%d", i);
}

您可以看到计数器 (i) 是在 for 循环体之外声明的。当用 C (和 C )写它时,我写:

1
2
3
4
for (int i = 0; i < 5; i++)
{
    printf("%d", i);
}

我对此进行了一些研究,似乎后者在 C89 中是非法的,并且仅在 C99 中引入。但是,我正在使用的教程是基于 C99 的,而且我还看到了很多现代 C 代码,其中计数器仍然在 for 循环体之外声明。

因此,我要问的问题是:在 C99 的 for 循环体之外声明计数器有什么实际好处吗?换句话说,我应该怎么写?

注意:我看到有"类似的问题",但他们中的大多数都在问为什么计数器在某些代码中的 for 循环体之外声明,而不是是否有任何好处.话虽如此,有一个类似的问题是在询问好处,但它是在 C 中,我不确定这两种语言在这方面是否存在差异。


for语句之前声明循环计数器的主要好处是:

  • 可移植到 C99 之前的编译器,
  • for 循环结束后访问此变量。

如果在 for 语句之前定义,则此变量在循环之后仍然有效并且在范围内,如果通过 break 语句退出循环,这可能非常有用:

1
2
3
4
5
6
7
8
9
10
11
12
void foo(void) {
    int i;
    for (i = 0; i < 100; i++) {
        if (bar(i))
            break;
    }
    ...
    if (i != 100) {
        printf("loop was exited after %d calls\
"
, i + 1);
    }
}

缺点是您以后不能在同一范围内以不同类型为另一个循环重复使用相同的标识符。

如果在for语句之后不需要访问循环计数器,在for语句的第一个子句中声明它可以提高可读性和可维护性。

相反,如果您需要可移植回 C99 之前的编译器,则应避免使用 C99 特有的功能,例如这个。