是否可以使用具有误导性语法的 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).
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).