C/C++ 中 前置++ 与 后置++ 逗号表达式 括号

使用vs2015

请看如下反汇编: 

	int m = 2;
00007FF6C78A5B88  mov         dword ptr [m],2  
	m++;
00007FF6C78A5B90  mov         eax,dword ptr [m]  //inc m
00007FF6C78A5B94  inc         eax  
00007FF6C78A5B96  mov         dword ptr [m],eax  

	int s = m + m * (m++) * m; //即使在括号中,m++的操作也被提到了表达式的最后
00007FF6C78A5B9A  mov         eax,dword ptr [m]  
00007FF6C78A5B9E  imul        eax,dword ptr [m]  
00007FF6C78A5BA3  imul        eax,dword ptr [m]  
00007FF6C78A5BA8  mov         ecx,dword ptr [m]  
00007FF6C78A5BAC  add         ecx,eax  
00007FF6C78A5BAE  mov         eax,ecx  
00007FF6C78A5BB0  mov         dword ptr [s],eax  //set value to s

00007FF6C78A5BB7  mov         eax,dword ptr [m]  //inc m
00007FF6C78A5BBB  inc         eax  
00007FF6C78A5BBD  mov         dword ptr [m],eax

	int s = m++*m *m++ + m++;
00007FF719505B90  mov         eax,dword ptr [m]  
00007FF719505B94  imul        eax,dword ptr [m]  
00007FF719505B99  imul        eax,dword ptr [m]  
00007FF719505B9E  add         eax,dword ptr [m]  
00007FF719505BA2  mov         dword ptr [s],eax   //set value to s

00007FF719505BA9  mov         eax,dword ptr [m]   //inc m
00007FF719505BAD  inc         eax  
00007FF719505BAF  mov         dword ptr [m],eax  

00007FF719505BB3  mov         eax,dword ptr [m]     //inc m
00007FF719505BB7  inc         eax  
00007FF719505BB9  mov         dword ptr [m],eax  

00007FF719505BBD  mov         eax,dword ptr [m]     //inc m
00007FF719505BC1  inc         eax  
00007FF719505BC3  mov         dword ptr [m],eax  


	int s = ++m*m *++m + ++m;  //前置++
00007FF64F585B90  mov         eax,dword ptr [m]  
00007FF64F585B94  inc         eax  
00007FF64F585B96  mov         dword ptr [m],eax  
00007FF64F585B9A  mov         eax,dword ptr [m]  
00007FF64F585B9E  inc         eax  
00007FF64F585BA0  mov         dword ptr [m],eax  
00007FF64F585BA4  mov         eax,dword ptr [m]  
00007FF64F585BA8  inc         eax  
00007FF64F585BAA  mov         dword ptr [m],eax  
00007FF64F585BAE  mov         eax,dword ptr [m]  
00007FF64F585BB2  imul        eax,dword ptr [m]  
00007FF64F585BB7  imul        eax,dword ptr [m]  
00007FF64F585BBC  add         eax,dword ptr [m]  
00007FF64F585BC0  mov         dword ptr [s],eax  
	++s = m;
00007FF64F585BC4  mov         eax,dword ptr [s]  
00007FF64F585BC8  inc         eax  
00007FF64F585BCA  mov         dword ptr [s],eax  
00007FF64F585BCE  mov         eax,dword ptr [m]  
00007FF64F585BD2  mov         dword ptr [s],eax  

	s = ++m *m++,b = --m + s--; //逗号表达式与++ -- 
00007FF79F655BC4  mov         eax,dword ptr [m]  //逗号前
00007FF79F655BC8  inc         eax  
00007FF79F655BCA  mov         dword ptr [m],eax  
00007FF79F655BCE  mov         eax,dword ptr [m]  
00007FF79F655BD2  imul        eax,dword ptr [m]  
00007FF79F655BD7  mov         dword ptr [s],eax  
00007FF79F655BDB  mov         eax,dword ptr [m]  
00007FF79F655BDF  inc         eax  
00007FF79F655BE1  mov         dword ptr [m],eax  

00007FF79F655BE5  mov         eax,dword ptr [m] //逗号后 
00007FF79F655BE9  dec         eax  
00007FF79F655BEB  mov         dword ptr [m],eax  
00007FF79F655BEF  mov         eax,dword ptr [s]  
00007FF79F655BF3  mov         ecx,dword ptr [m]  
00007FF79F655BF7  add         ecx,eax  
00007FF79F655BF9  mov         eax,ecx  
00007FF79F655BFB  mov         dword ptr [b],eax  
00007FF79F655C02  mov         eax,dword ptr [s]  
00007FF79F655C06  dec         eax  
00007FF79F655C08  mov         dword ptr [s],eax 


	s = ++m *m++,--m + s--;//可以发现逗号后面的表达式中的加法是没有运算的,只做了其中的前置减减和后置减减,该表达式相当于s = ++m *m++; --m + s--;
00007FF77C3A5BC4  mov         eax,dword ptr [m]  //逗号前面 s= ++m *m++
00007FF77C3A5BC8  inc         eax  
00007FF77C3A5BCA  mov         dword ptr [m],eax  
00007FF77C3A5BCE  mov         eax,dword ptr [m]  
00007FF77C3A5BD2  imul        eax,dword ptr [m]  
00007FF77C3A5BD7  mov         dword ptr [s],eax  
00007FF77C3A5BDB  mov         eax,dword ptr [m]  
00007FF77C3A5BDF  inc         eax  
00007FF77C3A5BE1  mov         dword ptr [m],eax  

00007FF77C3A5BE5  mov         eax,dword ptr [m] //逗号后面 
00007FF77C3A5BE9  dec         eax  
00007FF77C3A5BEB  mov         dword ptr [m],eax  
00007FF77C3A5BEF  mov         eax,dword ptr [s]  
00007FF77C3A5BF3  dec         eax  
00007FF77C3A5BF5  mov         dword ptr [s],eax  

	s = (1, 3);  //括号与表达式,有括号时,括号内作为一个整体的表达式 ,并且将括号中最后一部分作为表达式运算的部分。
00007FF73F6C5BA0  mov         dword ptr [s],3  
	s = (1, 2, 3,5,6);
00007FF6B9F35BF9  mov         dword ptr [s],6  

	s = (++m * m++)+1;
00007FF650985BAB  mov         eax,dword ptr [m]  
00007FF650985BAF  inc         eax  
00007FF650985BB1  mov         dword ptr [m],eax  
00007FF650985BB5  mov         eax,dword ptr [m]  
00007FF650985BB9  imul        eax,dword ptr [m]  
00007FF650985BBE  inc         eax  
00007FF650985BC0  mov         dword ptr [s],eax  
00007FF650985BC4  mov         eax,dword ptr [m]  //无逗号时括号内的后置++ 被挪到表达式结尾
00007FF650985BC8  inc         eax  
00007FF650985BCA  mov         dword ptr [m],eax  

	s = (++m * m++, --m + b--);//可以看到括号内逗号前面的乘法是没有运算的,由下面的汇编可以看出这个表达式等价为++m*m++; s = --m+b--; 逗号表达式加括号的方式可以用于插装。
00007FF73F6C5BA8  mov         eax,dword ptr [m]  //逗号前
00007FF73F6C5BAC  inc         eax  
00007FF73F6C5BAE  mov         dword ptr [m],eax  
00007FF73F6C5BB2  mov         eax,dword ptr [m]   //括号内 逗号前面的表达式 后置++ 被挪到提前执行了 。
00007FF73F6C5BB6  inc         eax  
00007FF73F6C5BB8  mov         dword ptr [m],eax  

00007FF73F6C5BBC  mov         eax,dword ptr [m]  //逗号后
00007FF73F6C5BC0  dec         eax  
00007FF73F6C5BC2  mov         dword ptr [m],eax  
00007FF73F6C5BC6  mov         eax,dword ptr [b]  
00007FF73F6C5BCA  mov         ecx,dword ptr [m]  
00007FF73F6C5BCE  add         ecx,eax  
00007FF73F6C5BD0  mov         eax,ecx  
00007FF73F6C5BD2  mov         dword ptr [s],eax  
00007FF73F6C5BD6  mov         eax,dword ptr [b]  
00007FF73F6C5BDA  dec         eax  
00007FF73F6C5BDC  mov         dword ptr [b],eax  


	int b = 0;
00007FF6F36E5B90  mov         dword ptr [b],0  
	int s = (b = ++m * m++, --m + b--) + ++b +b--; //相当于b = ++m * m++; s = ( --m + b--) + ++b +b--;
00007FF6F36E5B98  mov         eax,dword ptr [m]  //逗号前
00007FF6F36E5B9C  inc         eax  
00007FF6F36E5B9E  mov         dword ptr [m],eax  
00007FF6F36E5BA2  mov         eax,dword ptr [m]  
00007FF6F36E5BA6  imul        eax,dword ptr [m]  
00007FF6F36E5BAB  mov         dword ptr [b],eax  
00007FF6F36E5BAF  mov         eax,dword ptr [m]  
00007FF6F36E5BB3  inc         eax  
00007FF6F36E5BB5  mov         dword ptr [m],eax  

00007FF6F36E5BB9  mov         eax,dword ptr [m]  //逗号后
00007FF6F36E5BBD  dec         eax  
00007FF6F36E5BBF  mov         dword ptr [m],eax  
00007FF6F36E5BC3  mov         eax,dword ptr [b]  
00007FF6F36E5BC7  inc         eax  
00007FF6F36E5BC9  mov         dword ptr [b],eax  
00007FF6F36E5BCD  mov         eax,dword ptr [b]  
00007FF6F36E5BD1  mov         ecx,dword ptr [m]  
00007FF6F36E5BD5  add         ecx,eax  
00007FF6F36E5BD7  mov         eax,ecx  
00007FF6F36E5BD9  add         eax,dword ptr [b]  
00007FF6F36E5BDD  add         eax,dword ptr [b]  
00007FF6F36E5BE1  mov         dword ptr [s],eax  
00007FF6F36E5BE8  mov         eax,dword ptr [b]  
00007FF6F36E5BEC  dec         eax  
00007FF6F36E5BEE  mov         dword ptr [b],eax  
00007FF6F36E5BF2  mov         eax,dword ptr [b]  
00007FF6F36E5BF6  dec         eax  
00007FF6F36E5BF8  mov         dword ptr [b],eax  
	

一个完整的表达式可以是

a = a+1;//等于号左边的也属于表达式内。
a++;
b= (a++,a--);//这个相当于复合表达式了,理解为a++ ; b=a--; 
表达式 是以分号或逗号结尾。

可以确定:
1、后置加加(inc)或减减(dec)是在表达式结束的时候才进行运算的。
2、前置是在表达式之前进行运算的。
3、逗号表达式实际是多个独立的表达式。
4、括号中的逗号表达式是取逗号的最后一个表达式作为新表达式的部分。如b= (a++,a--);中,a-- 作为新表达式a=a--的部分。

需要注意的是不同编译器或不同语言结果是不一样的,链接
在线编译器

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章