以i ++为条件的C for循环的怪异行为

时间:2018-10-08 05:03:24

标签: c for-loop

我有以下代码:

int main()
{
    char i = 0;

    for (; i++; printf("%d", i));

    printf("%d", i);

    return 0;
}

它成功编译并打印1。我是C语言的新手,对此我不理解。我以为i ++永远都是真实的,因此它将是一个无限循环。

有人可以向我解释一下吗?

2 个答案:

答案 0 :(得分:3)

i++后递增。因此,在检查语句时,i的值为0,即false。因此,循环中断。

答案 1 :(得分:2)

    for (; i++; printf("%d", i));

合法 C代码,但不是惯用 C代码。真正的C程序员从不像这样编写代码(但可以理解会发生什么)。阅读n1570(实际上是C标准)第6.8.5.3节了解for的含义:

  

6.8.5.3 for语句

     

1陈述

      for ( clause-1 ; expression-2 ; expression-3 ) statement
     

表现如下:表达式expression-2是控制   在每次执行循环主体之前求值的表达式。   表达式expression-3在之后被评估为无效表达式   循环体的每次执行。如果第1条是声明,则   它声明的所有标识符的范围是   声明和整个循环,包括其他两个表达式;   在第一次评估之前按执行顺序达到   控制表达式。如果子句1是表达式,则为   在第一次评估之前被评估为无效表达式   控制表达式。158)

     

2子句1和表达式3都可以省略。省略   expression-2替换为非零常量。

     

脚注

     

158)因此,子句1指定了循环的初始化,可能是   声明一个或多个变量供循环使用;控制   表达式expression-2指定在每个表达式之前进行的评估   迭代,这样循环的执行将持续到   表达式比较等于0;和expression-3指定一个   每次执行之后执行的操作(例如递增)   迭代。

因此,在您的情况下,控制表达式(C标准中的“ expression-2”)是(错误地)i++。第一次循环时,它恰好是错误的。

如果将i++替换为++i,则该条件在Linux计算机上保持255次(因为我在8位上具有未签名的字符)。

如果您的计算机已签名,则从技术上讲,您有一些undefined behavior,因为您有签名的溢出。所以要非常 scared,然后在UB上阅读Lattner's blog

  

我是C语言的新手,对此我不理解。

然后,您应该阅读一些C reference网站,有时会参考C11标准n1570,阅读有关C编程的好书(也许甚至会读到关于编程的出色介绍,例如SICP- 不使用C),并学习how to debug small programs。如果您使用某些GCC编译器,请确保启用所有警告和调试信息,因此编译with gcc -Wall -Wextra -g