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--的部分。

需要注意的是不同編譯器或不同語言結果是不一樣的,鏈接
在線編譯器

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