是否可以使用具有误导性语法的 for 循环?

Is it possible to use for loop with misleading syntax?

for循环的语法:

for(initialization;condition;increment/decrement){
statements;
}

为什么下面的代码运行无限次然后为什么没有语法错误?

int x=10;
for(x++;x++;x++){
printf("\n %d",x);
}

您使用的“误导性语法”可能很奇怪而且很糟糕,但它仍然有效。这就是为什么您不会收到错误的原因。

循环中的三个子句是通用表达式,第一个例外(“初始化”表达式)允许作为变量定义。

你得到一个“无限”循环的原因是因为 x++ 永远不会为零(这是代表“假”的值)。但是,它会导致 未定义的行为 ,因为当您递增超过 int.

的限制时,它会导致算术溢出

如果将 for 循环翻译成相应的 while 循环,可能会更容易理解发生了什么(所有 for 循环都可以翻译为 while循环)。

for 循环

for (initialization; condition; increment/decrement)
{
    statements;
}

可以翻译成while循环

initialization;
while (condition)
{
    statements;
    increment/decrement;
}

如果我们现在对有问题的代码进行同样的翻译:

int x = 10;
for (x++; x++; x++)
{
    printf("\n %d",x);
}

变成

int x = 10;
x++;  // initialization
while (x++)  // condition
{
    printf("\n %d",x);  // statements
    x++;  // increment/decrement
}

这可能会更清楚发生了什么以及为什么会出现“无限”循环。

Why is the below code running infinite times...?

因为使用的条件不会阻止它执行,因为它通常 永远不会计算为 0

x 在每次迭代中递增两次,直到达到宏 INT_MAX (limits.h) 中定义的值。在那之后,递增 x 会调用 undefined behavior.

...and then why there is no syntax error?

x++ 是有效条件,编译器不会检查您设置为条件的表达式是否有意义。它只检查语法错误。所以程序可以编译,当运行时,无限循环

所以要回答:

Is it possible to use for loop with misleading syntax?

答案是:是的。但在这种情况下,它会在某个时候调用如上所述的未定义行为。

for 循环的 3 个子句是可选的,唯一的要求是它们应该是有效的表达式 - 第一个可以选择包含变量声明。语法有效。

在第二个子句中,表达式的结果被用作对零的检查。您从 10 开始,所以第一次检查读取值 10,依此类推。它永远不会为零,因此循环不会终止。

除此之外,每个for子句后都有一个序列点,因此代码就序列而言也是有效的。此代码将继续计数,直到遇到整数溢出,这是未定义的行为。

for循环在C标准中有两种定义方式

for ( expressionopt ; expressionopt ; expressionopt ) statement
for ( declaration expressionopt ; expressionopt ) statement

所以这个for循环

for ( x++; x++; x++ ){

具有与 for 循环的第一个定义相对应的正确形式。

循环会一直执行到第三个表达式x++之后的值x等于0.

如果您使用 unsigned int 类型而不是 int 类型,您将得到一个正确的有限循环,因为不会出现导致有符号 int 类型出现未定义行为的溢出。

unsigned int x=10;
for(x++;x++;x++){
printf("\n %d",x);
}

为了使循环更清晰,让我们在您的示例中使用变量 x 的初始值将等于 -3.

int x = -3;
for ( x++; x++; x++ ){
    printf("\n %d",x);
}

所以在第一个表达式 x++ x 将等于 -2 之后,因为 -2 不等于 0 循环体将获得控制权并且 printf 语句将输出-1 因为 x 在条件中也增加了。

然后将计算第三个表达式 x++。 x 将等于 0。

所以现在条件 x++ 将被评估为逻辑假,因为它是 x 在递增之前的值。

来自 C 标准(6.5.2.4 后缀递增和递减运算符)

2 The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it).