简体   繁体   English

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

[英]Weird behaviour of C for loop with i++ as condition

I have the following code: 我有以下代码:

int main()
{
    char i = 0;

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

    printf("%d", i);

    return 0;
}

It successfully compiles and prints 1 . 它成功编译并打印1 I am new to C and I don't understand this. 我是C语言的新手,对此我不理解。 I thought i++ will always be true and so it will be an infinite loop. 我以为i ++永远都是真实的,因此它将是一个无限循环。

Can someone please explain this to me? 有人可以向我解释一下吗?

i++ is post-increment . i++后递增的 So at the time of checking the statement, the value of i is 0 , which is false . 因此,在检查语句时, i值为0 ,这是false Hence, the loop breaks. 因此,循环中断。

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

is legal C code, but is not idiomatic C code. 合法的 C代码,但不是惯用的 C代码。 Real C programmers never code like this (but can understand what happens). 真正的C程序员从不像这样编写代码(但可以理解会发生什么)。 Read n1570 (it practically is the C standard) §6.8.5.3 for the meaning of for : 阅读n1570 (它实际上是C标准)§6.8.5.3的含义for

6.8.5.3 The for statement 6.8.5.3 for语句

1 The statement 1声明

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

behaves as follows: The expression expression-2 is the controlling expression that is evaluated before each execution of the loop body. 其行为如下:表达式expression-2是控制表达式,该表达式在每次执行循环主体之前进行评估。 The expression expression-3 is evaluated as a void expression after each execution of the loop body. 每次执行循环体后,表达式expression-3都将被评估为无效表达式。 If clause-1 is a declaration, the scope of any identifiers it declares is the remainder of the declaration and the entire loop, including the other two expressions; 如果子句1是一个声明,则它声明的任何标识符的范围是声明的其余部分和整个循环,包括其他两个表达式; it is reached in the order of execution before the first evaluation of the controlling expression. 在第一次对控制表达式求值之前按执行顺序达到它。 If clause-1 is an expression, it is evaluated as a void expression before the first evaluation of the controlling expression.158) 如果子句1是一个表达式,则在对控制表达式进行第一次求值之前,它会被视为空表达式(158)

2 Both clause-1 and expression-3 can be omitted. 2子句1和表达式3都可以省略。 An omitted expression-2 is replaced by a nonzero constant. 省略的expression-2替换为非零常量。

Footnotes 脚注

158) Thus, clause-1 specifies initialization for the loop, possibly declaring one or more variables for use in the loop; 158)因此,第1节指定了循环的初始化,可能会声明一个或多个变量供循环使用; the controlling expression, expression-2, specifies an evaluation made before each iteration, such that execution of the loop continues until the expression compares equal to 0; 控制表达式expression-2指定在每次迭代之前进行的求值,以便继续执行循环,直到表达式比较等于0为止; and expression-3 specifies an operation (such as incrementing) that is performed after each iteration. 而expression-3指定在每次迭代之后执行的操作(例如递增)。

So, in your case, the controlling expression (the " expression-2 " in the C standard) is (wrongly) i++ . 因此,在您的情况下,控制表达式(C标准中的“ expression-2 ”)是(错误地) i++ It happens to be false on the first time the loop is taken. 第一次执行循环时,它恰好是错误的。

If you replace i++ by ++i the condition stays true for 255 times on my Linux computer (since I have unsigned chars on 8 bits). 如果用++i代替i++ ,则该条件在我的Linux计算机上保持255次(因为我在8位上具有未签名的字符)。

If your computer has signed chars, you technically have some undefined behavior , because you have a signed overflow. 如果您的计算机已对字符进行签名,那么从技术上讲,您将具有一些未定义的行为 ,因为您已签名了溢出。 So be very scared and read Lattner's blog on UB! 因此,请非常 害怕,并在UB上阅读Lattner的博客

I am new to C and I don't understand this. 我是C语言的新手,对此我不理解。

Then you should read some C reference site, sometimes refer to the C11 standard n1570 , read good books on C programming (perhaps even read good introduction to programming, such as SICP - which does not use C), and learn how to debug small programs . 然后,您应该阅读一些C参考站点,有时参考C11标准n1570 ,阅读有关C编程的好书(也许甚至阅读了很好的编程入门,例如SICP- 使用C),并学习了如何调试小型程序。 If you use some GCC compiler, be sure to enable all warnings and debug info, so compile with gcc -Wall -Wextra -g . 如果使用某些GCC编译器,请确保启用所有警告和调试信息,因此请使用 gcc -Wall -Wextra -g编译。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM