for循环第一个语句应该是声明

时间:2014-02-26 11:05:33

标签: c

main ()
{
      char i = 0;
      for (i <= 5 && i >= -1; ++i; i > 0)
          printf ("%d", i);
      getch ();
}

我是一名Java学生,最近我开始做C程序。我在C书中看到了这个问题。我对这个程序有以下疑问:

  1. 这个程序汇编得很好。这应该不会导致编译错误吗? for循环的第一部分应该是一个声明,但这里是一个布尔表达式。
  2. 输出为1,2,3,4.....126,127,-128....-2,-1。为什么输出停在-1?这应该是一个无限的系列,永远重复上述系列。

3 个答案:

答案 0 :(得分:6)

For循环由三个表达式组成,因此这个例子编译得很好。第一个是i <= 5 && i >= -1。它什么都不做。第二个是循环停止的条件。在您的情况下,++i表示当i达到值0时循环停止。第三部分i>0不执行任何操作。所以你的周期:

  for (i <= 5 && i >= -1; ++i; i > 0)
      printf ("%d", i);

相当于:

  i <= 5 && i >= -1;
  while (++i) {
      printf ("%d", i);
      i>0;
  }

相当于:

  while (++i) {
      printf ("%d", i);
  }

答案 1 :(得分:4)

(有些人现在不得不吃一些奇怪的东西)

在MinGW32(标志:-Wall -pedantic -std=c99)上使用GCC-4.8.1进行编译时,我只收到以下警告:

In function 'main':
6:7: warning: statement with no effect [-Wunused-value]
       for (i <= 5 && i >= -1; ++i; i > 0)
       ^
6:7: warning: statement with no effect [-Wunused-value]

这可以解释如下。正如评论中所提到的,for - 循环的语法只是for(expression-1; expression-2; expression-3)(其中每个表达式也可以为空)。此外,for - 循环可以被视为while - 循环的语法 - 糖,它确实可以翻译为:

expression-1;
while(expression-2){
    body;
    expression-3;
}

在您的情况下,它转换为:

i <= 5 && i >= -1;
while (++i) {
    printf ("%d", i);
    i > 0;
}

然后GCC警告表达式-1和表达式-3,因为它们有效并产生一个值,但是该值被丢弃并且表达式没有副作用。优化编译器时,可能甚至不会在生成的代码中包含这些表达式,因为它们没有任何效果。

它永远不会循环的原因是因为最终++i会溢出并且机器中的编译器/平台/ gnomes已经决定将其环绕以使其变为负数并最终返​​回最多0:停止循环。请注意,这严格来说是未定义的行为,因为它调用了signed-integer-overflow。

答案 2 :(得分:3)

  1. 第一部分可以是任何有效的C表达式。它甚至可以留空。但是,使用它为循环变量赋予初始值是自定义的。

  2. char很快溢出,当第二个表达式++i的值达到0时,循环停止。