轉自:
http://c.chinaitlab.com/cc/basic/200908/790961.html逗號操作符?
C++里有逗號操作符么?
不少C++ newbie都會問到這問題,大家對+-*/自然是認識的了,對其他的%!&|之類的也不覺得陌生,但是逗號操作符?可能有一半的人會說不清楚它到底是干啥的。
其實,我們是經常會用到逗號操作符的,但是并不是所有代碼里出現的逗號都是逗號操作符。
讓我們先從一個類的示例代碼開始:
1: 2: class mynum 3: { 4: public: 5: mynum(double ndb,...) 6: { 7: //init with arguments 8: } 9: }; 10: class someclass 11: { 12: someclass(): 13: num(3,4) 14: ,a(0) 15: ,b(0) 16: ,c(15) 17: { 18: int i,j; 19: i=1,2; //int x=1,2; 20: for(;b<10;++b,--c) 21: { 22: ++a; 23: } 24: } 25: mynum num; 26: int a; 27: int b,c; 28: };
|
在這段代碼里,逗號在5,13-16,18-20,27行都出現了。
現在先讓我們來看看逗號操作符是啥意思:
一個包含逗號的表達式首先計算逗號左邊的表達式,然后計算逗號右邊的表達式;整個表達式的結果是逗號右邊表達式的值。
然后我們看看上面的代碼:
第5行是在mynum類的構造函數里出現的逗號,只是用來區分開第一個double類型的參數和后面的可變參數。這是一個特例,如果在構造mynum對象的時候,本來是要傳入3.4作為第一個參數的,結果不小心把小數點變成了逗號的話,3.4就變成了兩個參數3和4——比如在第13行的情況。類似這樣的情況編譯器不會報錯,程序也能運行,但是mynum類里的成員變量可能就因為構造函數傳入的變量值變化而導致程序運行結果完全不一致了。這兩個逗號都不是逗號操作符了。
第14,15,16行的逗號,也不是逗號操作符。這三個逗號只是用來間隔構造函數的成員變量初始化列表。
第18行的int i,j;是大家都很常用的變量聲明的語句,逗號在這里,也只是起了一個間隔變量聲明的作用,也不是逗號運算符。
第19行的逗號,如果不認識逗號操作符的話,一定會認為這肯定是寫錯了!其實這正是逗號操作符了。讓我們看看,經過i=1,2;這個語句后,i 的值應該是多少呢?按照之前逗號操作符的定義,我們好像可以很輕松的得出i=2.然而,這個答案是錯的!你在得出錯誤答案的時候,忽略了一個重要的因素——運算符優先級!由于=號的優先級更高,所以i=1,2;這個語句相當于(i=1),2; ,如果要得到期望的2,我們應該這樣來寫i=(1,2);。下面的代碼可以驗證這個說法的(注意第3行是無意義代碼,但是可不是錯誤代碼哦!)
1: int i,j; 2: i=1,2; 3: 3,4; 4: j=(1,2); 5: printf("%d\n%d\n",i,j);
|
繼續看第一份代碼里的第20行,這是一個for循環代碼。這里的逗號,也是逗號操作符哦。其實for循環也是逗號操作符經常出現的地方哦。for循環里只能寫一個表達式,而逗號表達式這個時候就可以讓你完成兩個甚至多個表達式的計算。比如“for(;b<10;++b,——c)”,++b和——c就會在每次循環中都被執行到。
第27行就無須多說了。也就是一普通的變量聲明語句,這里的逗號也不是逗號操作符的。
總的來說,逗號操作符并不是一個非常常用的操作符,它只在某些特定的上下文環境里會有很好的效果,同時,在編碼中還要非常小心錯誤的輸入的逗號引發錯誤的問題。
比如逗號和括號就會引發一些潛在問題,如果在編碼的時候一疏忽就會產生一些難以追查的隱藏bug,只有遵守一些既定的編碼規范,養成良好嚴謹的編碼習慣,才有助于避免一些諸如此類的問題出現。看看下面的代碼:
1: int myadd(int i,int j,int k) 2: { 3: return i+j+k; 4: } 5: int myadd(int i,int j) 6: { 7: return i+j; 8: } 9: 10: int main() 11: { 12: 13: for(int x=0;x<9;++x) 14: { 15: printf("%d",myadd((2,3),4)); 16: } 17: }
|
由于在第15行,錯誤的添加了括號(在實際編碼中這樣的情況太常見了),結果導致整個的輸出全錯了!因為(2,3)這個逗號表達式的返回值是3,所以15行相當于是myadd(3,4)了!
so,一定要記住啦,小心,小心,再小心!^_^