C 增量运算符的问题

C 增量运算符的问题,c,operators,C,Operators,这是我在入门级计算机编程课程中遇到的示例代码: #include <stdio.h> int main() { int l = 20, m = 10; int z; z= l++ || m++; printf("z = %d l = %d m = %d\n", z, l, m); } #包括 int main() { int l=20,m=10; intz; z=l++|m++; printf(“z=%d l=%d m=%d\n”,z

这是我在入门级计算机编程课程中遇到的示例代码:

 #include <stdio.h>
 int main()
 {
     int l = 20, m = 10;
     int z;
     z= l++ || m++;
     printf("z = %d l = %d m = %d\n", z, l, m);
 }
#包括
int main()
{
int l=20,m=10;
intz;
z=l++|m++;
printf(“z=%d l=%d m=%d\n”,z,l,m);
}
代码打印l=21、m=10和z=1
l和z的值是我所期望的,但m的值让我感到不安。它不应该是11,因为m++存在于代码中。

这是因为
m++
只有在
l++==0时才会执行。由于
l++
的计算结果为
20
,因此永远不会执行
m++
。如果
l
最初是
0
,则将执行
m++

这是因为
m++
仅在
l++==0
时才会执行。由于
l++
的计算结果为
20
,因此永远不会执行
m++
。如果
l
最初为
0
,则将执行
m++

z= l++ || m++;
在表达式中,
l
首先赋值,然后递增一

逻辑或(| |)运算中,如果左操作数为非零,则右操作数未计算,结果为真。这就是为什么
l
变成
21
而m没有被计算,它的值是
10

C标准(N1256:6.5.14-第4段)规定:

与按位|运算符不同,| |运算符保证 从左到右评价后有一个序列点 第一个操作数的求值。如果第一个操作数比较不相等 如果设置为0,则不计算第二个操作数

在表达式中,
l
首先赋值,然后递增一

逻辑或(| |)运算中,如果左操作数为非零,则右操作数未计算
,结果为真。这就是为什么
l
变成
21
而m没有被计算,它的值是
10

C标准(N1256:6.5.14-第4段)规定:

与按位|运算符不同,| |运算符保证 从左到右评价后有一个序列点 第一个操作数的求值。如果第一个操作数比较不相等 如果设置为0,则不计算第二个操作数


你所看到的就是所谓的短路评估

你的台词是:

 z= l++ || m++;
表示,检查l的值(检查时增加)。如果l不是0,则将z设置为1。如果l为0,则检查m的值(检查时增加)。如果m不是0,则将z设置为1。否则,将z设置为0


本质上,当两个检查(
l++
)中的第一个已经计算为真时,系统不需要检查第二个条件,因此它没有,因此也无法增加m。您看到的称为短路计算

你的台词是:

 z= l++ || m++;
表示,检查l的值(检查时增加)。如果l不是0,则将z设置为1。如果l为0,则检查m的值(检查时增加)。如果m不是0,则将z设置为1。否则,将z设置为0


基本上,当两个检查(
l++
)中的第一个检查的结果为true时,系统不需要检查第二个条件,因此它不需要,因此也无法增加m。

如果你知道
z=1
是正确的,那么你就可以找出为什么
m++
从未被执行。如果你知道
z=1
是正确的,那么你就可以找出
m++
从未被执行的原因。你的意思是说它首先被计算,对吗?@Iharob,首先检查左操作数值,如果为真,则不要检查右操作数值。@KeineLust感谢您的建议。挑剔:递增是在赋值之前还是之后进行的,未指定。增量后运算符的所有保证是,增量之前的值已产生,并且在下一个序列点完成了输入。哦,C99不是标准的,它在6年前随着C11的发布而被取消。它在这里没有什么区别,但无论如何你都应该更新你的文档。你的意思是首先计算它,对吗?@Iharob在“逻辑与运算”中,首先检查左操作数值,如果是真的,则不要检查正确的操作数值。@KeineLust谢谢您的建议。挑剔:递增是在赋值之前还是之后进行的是未指定的。增量后运算符的所有保证是,增量之前的值已产生,并且在下一个序列点完成了输入。哦,C99不是标准的,它在6年前随着C11的发布而被取消。这并没有什么区别,但无论如何你都应该更新你的文档。我认为最好解释一下短路评估,更好地理解原因。我认为最好解释一下短路评估,更好地理解原因。