我编写了以下代码:
int main(){
int i=-1,j=-1,k=0,l=2,m;
m = i++ && j++ && k++ || l++;
printf("%d %d %d %d %d",i,j,k,l,m);
i=-1,j=-1,k=0,l=2,m;
m = ++i && ++j && ++k || ++l;
printf("\n%d %d %d %d %d",i,j,k,l,m);
return(0);
}
我得到了以下结果:
0 0 1 3 1
0 -1 0 3 1
据我所知,后缀和前缀运算符是在分号之后解决的,即。原始值用于表达式中,然后变量自行解析。 在这种情况下
i++ && j++
应该等于
++i && ++j
两者都应该等同于
i && j;
i = i+1;
j = j+1;
因此两个表达式的结果必须相同。 但事实并非如此。 请任何人都可以帮助我,我哪里有错误的概念。
最佳答案
i++ && j++
绝对不等于 ++i &&++j
。
以两者都为零的情况为例 - 第一个结果为:
0 && j++
产生 0 结果(并且由于短路,j 甚至不会增加)。
在第二种情况下,你会得到
1 && 1
产生 1 个结果。
考虑到这一点,让我们看一下您的示例(为了便于阅读而添加了空格、分号和换行符):
首先:
int i = -1; int j = -1; int k = 0; int l = 2; int m = i++ && j++ && k++ || l++;
我们首先将其完全括起来,以便于处理:
int m = ((i++ && j++) && k++) || l++;
那么,接下来会发生什么呢?首先是
i++
。i
递增(并变为0
),但由于它是后递增,因此表达式的结果为-1
。这给出:int m = ((-1 && j++) && k++) || l++;
由于
&&
的左侧非零,因此计算右侧。j++
将j
递增到0
,但同样,后递增意味着表达式的值为-1
。int m = ((-1 && -1) && k++) || l++;
解决
&&
:int m = (1 && k++) || l++;
接下来,右边剩下的
&&
。k
递增,变为1
,但表达式产生0
:int m = (1 && 0) || l++;
解决这个
&&
:int m = 0 || l++;
最后,由于
||
的左侧为 0,因此计算右侧。l
递增,变为3
,但作为后递增,产生2
:int m = 0 || 3;
最后:
int m = 1;
一路走来,我们最终得到了:
i = 0; j = 0; k = 1; l = 3;
解释你的第一个打印输出。
接下来,让我们看第二个示例(更简洁;如果您需要更多详细信息,请告诉我):
int i = -1, j = -1, k = 0, l = 2, m; m = ((++i && ++j) && ++k) || ++l; // parenthesized for readability ^ // i is pre-incremented m = (( 0 && ++j) && ++k) || ++l; ^ // first && operator short-circuits m = (0 && ++k) || ++l; ^ // second && operator short-circuits m = 0 || ++l; ^ // l is pre-incremented m = 0 || 3; ^ // evaluate || operator m = 1;
结果是:
i = 0 j = -1 k = 0 l = 3 m = 1
打印出来的正是您所看到的内容。
关于c - 如何解决后缀和前缀运算符表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16991936/