C语言中的for循环初值声明

63

有人能详细解释一下以下的gcc错误吗?

$ gcc -o Ctutorial/temptable.out temptable.c 
temptable.c: In function ‘main’:
temptable.c:5: error: ‘for’ loop initial declaration used outside C99 mode

temptable.c:

...
/* print Fahrenheit-Celsius Table */
main()
{
    for(int i = 0; i <= 300; i += 20)
    {
        printf("F=%d C=%d\n",i, (i-32) / 9);        
    }
}

P.S: 我模糊地记得在 for 循环之前应该声明 int i。我应该说明我正在寻找一个能够提供 C 标准历史背景的答案。


2
请查看与C变量声明相关的此前问题以获取更多信息:https://dev59.com/DHVC5IYBdhLWcg3wcw0m - Kyle Walsh
请注意,温度转换公式是不正确的。在整数运算中,应该是(5 * (i - 32)) / 9(少了 5)。通常,你需要浮点数运算-但是你还需要把你的printf格式从 C =%d 改为 C =%./ 2f 或类似的方式(并且你要用 (5.0 * (i - 32)) / 9.0 进行转换)。 - Jonathan Leffler
2个回答

106
for (int i = 0; ...) 

-std=c99是C99引入的语法。为了使用它,您必须通过向GCC传递-std=c99(或更高版本)来启用C99模式。 C89版本如下:

int i;
for (i = 0; ...)

编辑

在历史上,C语言一直强制程序员在块的开始处声明所有变量。所以像这样的代码:

{
   printf("%d", 42); 
   int c = 43;  /* <--- compile time error */

必须重写为:

{
   int c = 43;
   printf("%d", 42);

一个块被定义为:

block := '{' declarations statements '}'

C99、C++、C#和Java允许在块的任何位置声明变量。

真正的原因(猜测)是为了在解析C源代码时尽快分配内部结构(如计算堆栈大小),而不需要进行另一个编译器通道。


7
请注意:在使用c99版本时,不要忘记所声明的变量仅存在于for循环块内部,并且在超出其作用域后将不存在。 - ely
4
可能有历史意义的附加注释。在 C99 标准之前,避开这个规则的一种方法是在一个块内创建另一个块。你可以在一个块的中间声明一个变量,并用更多的大括号 {} 包围它和使用它的代码。 - Neil Roy
1
值得一提的是,例如在新版本的GCC上,默认的C版本已经更新到比C89更高的版本,因此这整个问题不会导致编译错误...(我正在Ubuntu 16.04上使用gcc 5.4.0,并且对于这段代码片段没有任何编译错误或警告)。 - Guy Avraham
如果有人真的想要尝试使用编译器标志“-std=c89”进行实验,只需添加一个单词即可:不要忘记添加“-pedantic”以要求编译器认真对待。 - aafulei

20

C99之前,您必须在代码块的开头定义局部变量。 C99引入了C++的特性,允许您将局部变量定义与指令混合使用,并且您可以在forwhile控制表达式中定义变量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接