a++,++a,+=,=讨论

值得注意的是:++a接受赋值时的值的变化

 

#include <iostream>
using namespace std;

int main()
{
 int a=4;
 a += (a++);  //a=a+(a++); a=9

 a=4;
 a += (++a);  //a=a+(++a); a=10

 //-------------------------------------------------------------------------------------------------
 //以下两句的执行,a值的变化?????
 a=4;
 (++a) += (a++); //5=5+6  a=11
 //1.接受赋值之前:++a,a=5
 //2.右值:a++,5,a=6
 //3.赋值之后:5+6=11

 a=4;
 (++a) += (++a); //  a=12
 //-------------------------------------------------------------------------------------------------

 a=4;
 (++a) = (a++) + (++a) ; //a=13  //加法交换律

 a=4;
 (++a) = (++a) + (a++); // a=13
 //1.接受赋值之前,++a,a=5
 //2.右值的计算:++a:6,a=6   a++:6,a=7(a自增1)
 //3.整个表达式的值:6+6,再加上a的自增1,所以,a赋值之后的值为13

 a=5;
 int c = (++a) + (a++); // c=12,a=7 (问题:c=12的值,是12=5+7,还是12=6+6 ??? 经验证,是12=6+6)

 a=4;
 ++a = ++a;  // a=6

 a=4;
 ++a = a++;  // a=6

 a=4;
 ++a = a;  //a=5

 //(a++) += a;  //这种写法错误,左侧不是一个有效变量,不能赋值,可改为(++a) += a;

 a=4;
 (++a) += a; //5+5;   a=10

 a=4;
 a = a++;    //a=5
 a=4;
 int b=a++;  //b=4
 a=4;
 a = (a++);  //a=5
 a=4;
 b=(a++);    //b=4

 return 0;
}

 

 

 

 

 

 

//-------------------------------------------------------------------------------------------------------------------------------------------

问题点:计算机是不会骗人的,所以得到的输出结果都是正确的。这里要说的是楼主要注意以下几个细节:
1. 第一个结果5,是 a=5,而不是(a++)+(a++)=5
2. 第二个结果是(++a)+(++a)=10,而不是a=10
3. 有一点楼主很有必要说明,那就是等式的左边是什么?要知道下面这两个赋值语句结果会大相径庭。
k=(a++)+(a++);
a=(a++)+(a++);


正确答案:
k=(a++)+(a++); 的情况下:k=6,a=5(这个a=5验证了楼主得到的第一个结果)
k=(++a)+(++a); 的情况下:a=5,k=10 (这个k=10验证了楼主得到的第二个结果)
简单来说,上面两个等式,无论怎么计算,a的值只做过两次自加运算,所以a一定等于5。
在看下面两个等式:
a=(a++)+(a++); 的情况下:a=8
a=(++a)+(++a); 的情况下:a=10


详细解释:

我们都知道的真理是:
a ++:先计算在加
++ a:先加在计算

虽然这两句话是绝对正确的,不过在复杂的场合只用这两句话是解释不清楚的。想要真正理解上面4个表达式,只能考虑内存的实际存储过程,最能显示内存存储过程的……当然是汇编语言。下面用反汇编写出的代码说明了a++和++a的本质,如果可以理解,这一生,也不会再为自加运算犯愁了。下面的解释,如果没有学过汇编的话,就只看注释,了解它的过程就可以了。如果实在看不懂,就放弃,因为这种代码在实际编程届是不允许出现的。高级工程师是要做出所有人都看得懂的程序,小程序员才会编出只有自己才看得懂的程序。所以,下面的解释,建议楼主只供学习参考用。

等式1*****************
int a=3;
int k=0;
k=(a++)+(a++);

反汇编
8: int a=3;
00401028 mov dword ptr [ebp-4],3//a的地址是dword ptr [ebp-4]
9: int k=0;
0040102F mov dword ptr [ebp-8],0//k的地址是dword ptr [ebp-8]
10: k=(a++)+(a++);
00401036 mov eax,dword ptr [ebp-4]// 把3放入eax中,eax可以想象成临时变量
00401039 add eax,dword ptr [ebp-4]// 把3+3=6放入eax中
0040103C mov dword ptr [ebp-8],eax//把eax中的6移回k中
0040103F mov ecx,dword ptr [ebp-4]//把a的值移到ecx中
00401042 add ecx,1 // ecx的值+1
00401045 mov dword ptr [ebp-4],ecx//a地址中的值加1,a=4
00401048 mov edx,dword ptr [ebp-4]//把a的值移到edx中
0040104B add edx,1 // 寄存器中的值加1,a=5
0040104E mov dword ptr [ebp-4],edx//移回a地址
结论:k=*( dword ptr [ebp-8])=6;a=5

等式2*****************
int a=2;
int k=0;
k=(++a)+(++a);

反汇编:
8: int a=2;
00401028 mov dword ptr [ebp-4],3// a的地址是dword ptr [ebp-4]
9: int k=0;
0040102F mov dword ptr [ebp-8],0//k的地址是dword ptr [ebp-8]
10: k=(++a)+(++a);//a先加
00401036 mov eax,dword ptr [ebp-4]
00401039 add eax,1//寄存器中的值加1
0040103C mov dword ptr [ebp-4],eax//a=4
0040103F mov ecx,dword ptr [ebp-4]
00401042 add ecx,1//对a地址中的值加1,a=5
00401045 mov dword ptr [ebp-4],ecx
00401048 mov edx,dword ptr [ebp-4]
0040104B add edx,dword ptr [ebp-4]//a+a=10
0040104E mov dword ptr [ebp-8],edx//值移入k地址中k=10
结论:k=*( dword ptr [ebp-8])=10;a=5

等式3*****************
int a=2;
int k=0;
a=(a++)+(a++);

反汇编
:
8: int a=2;
00401028 mov dword ptr [ebp-4],3//同上
9: int k=0;
0040102F mov dword ptr [ebp-8],0
10: a=(a++)+(a++);
00401036 mov eax,dword ptr [ebp-4]
00401039 add eax,dword ptr [ebp-4] //同上
0040103C mov dword ptr [ebp-4],eax//同上,不同的是计算结果存入a地址a=6
0040103F mov ecx,dword ptr [ebp-4]
00401042 add ecx,1//寄存器中的值加1,
00401045 mov dword ptr [ebp-4],ecx//a=7
00401048 mov edx,dword ptr [ebp-4]
0040104B add edx,1//寄存器中的值加1
0040104E mov dword ptr [ebp-4],edx//a=8
结论:a=*( dword ptr [ebp-4])=8;

等式4*****************
int a=2;
int k=0;
a=(++a)+(++a);
反汇编:
8: int a=2;
00401028 mov dword ptr [ebp-4],3
9: int k=0;
0040102F mov dword ptr [ebp-8],0
10: a=(++a)+(++a);
00401036 mov eax,dword ptr [ebp-4]
00401039 add eax,1
0040103C mov dword ptr [ebp-4],eax
0040103F mov ecx,dword ptr [ebp-4]
00401042 add ecx,1
00401045 mov dword ptr [ebp-4],ecx
00401048 mov edx,dword ptr [ebp-4]
0040104B add edx,dword ptr [ebp-4]
0040104E mov dword ptr [ebp-4],edx
结论:a=*( dword ptr [ebp-4])=10;


上面的代码,只有第一个注释比较详细,因为反汇编代码都是一样的,不做赘述。如果可以理解上面的代码,那么下面的等式可以马上得出答案。

int k=2;
int val =0;
val=(++k)+(++k)+(k++)+(++k)+(++k) +(++k) +(++k) +(k++)+(k++)+(k++);
val=4 + 4 +4 +5 +6 +7 +8 +8 +8 +8= 62

悉雨辰寂
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值