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的发布而被取消。这并没有什么区别,但无论如何你都应该更新你的文档。我认为最好解释一下短路评估,更好地理解原因。我认为最好解释一下短路评估,更好地理解原因。