//sample.CPP # includeiostreamusingnamespacestd; int main () {int i=1; printf(case1:%d,%dn ),i--,I ); i=1; printf(case2:%d,%d(n ),I,I ); i=1; printf(case:%d、%d、%dn )、I、I、I ); 返回0; }执行结果:
原因:
参考链接: https://blog.csdn.net/u 014644714/article/details/77688321
---
先看一些情况
1、
int i=1; printf('%d,%d(n ),i--,I ); 运行结果是2,1这与编译器有关,通过汇编可以清楚地看到
步骤1 :将I的值存储在缓冲区中[ebp-0E8h]=1;
步骤2:I值加1,i=i 1=2;
步骤3 (将I的值存储在缓冲器中(ebp-0ech )=2;
步骤4:I值减去1,i=i-1=1;
步骤5 :将缓冲区[ebp-0E8h]=1放入堆栈
步骤6 :将缓冲区[ebp-0ECh]=2放入堆栈
因此,打印输出为2、1
总结:
或--运算的顺序是从右到左,所以先计算I。 I在计算过程中生成缓冲区。 返回的值是缓冲区的值,必须在加1之前进行备份。 此处的缓冲区地址为[ebp-0E8h]=1。
然后,i=i 1=2;
同样,第二个表达式的缓存区域[ebp-0ECh]=2表示,
然后,i=i-1=1;
然后,将第1、第2个式返回值分别放入堆栈【1、2】中,所以输出为2 1;
2,
int i=1; printf('%d,%dn ),I,I );
步骤1:I值加1,i=i 1=2;
步骤2 :将I的值存储在缓冲区中[ebp-0E8h]=2;
步骤3:I值加1,i=i 1=3;
步骤4 :将4:I=3放入堆栈
步骤5 :将缓冲区[ebp-0E8h]=2放入堆栈
因此,输出为2、3
总结:
或--运算的顺序是从右到左,所以先计算I。 I的返回值是I本身,应该是2,但之后的运算会影响I的值。 此外,printf输出流的缓存堆栈在计算完所有表达式后重新堆栈。 您只需要知道第一个堆栈是存储在I的地址中的值。
下面的公式I,I在计算过程中生成缓冲区。 返回的值是缓冲区的值,必须在加1之前进行备份。 此处的备份地址为[ebp-0E8h]=2,然后i=i 1=3,返回的值为缓冲区[ebp-0E8h]=2,第二次堆栈的是第二个表达式的返回值。
以下几个示例具有两个变量: 道理很相似。 请注意,带有后置/--的返回缓存区域的值,而前置的返回变量本身的值。 另外,自己的值可能会受到其他公式的影响,所以在计算结束之前不知道I的值。
1、
int x=2,y=3; printf('%d,%dn ),) x ) y,y ); //等价x y
首先堆栈的是y值本身,其他公式对此没有影响,所以堆栈的y==4
第二个堆栈是表达式缓冲器的值,x y=2 4=6,所以进入堆栈6
输出值为64
下面的例子请自己分析一下。 如果你看反汇编,你很快就会明白它的意思。 不一一说明
2,
int x=2,y=3; printf('%d、%dn )、x y、y );
3、
int x=2,y=3; printf('%d、%dn )、x y、y );
4,
int x=2,y=3; printf('%d、%dn )、x y、y );