(沒有意義討論)二元運算符和自加符的深入理解,小心多個++的陷阱


(文章使用gcc-4.6.2編譯,本文不嚴謹的討論了y=(++i)+(++i)+(++i)+(++i)表達式求值問題,其實這個討論是沒有意義的,原因參見:

http://www.cnblogs.com/pmer/archive/2013/01/02/2842516.html

最近看到了一道c語言題目,題目是這樣的:

int x,y,i=3;
x=(i++)+(i++);
i=3;
y=(++i)+(++i);
問x和y的值分別是多少?

答案: x的值很容易看出來,是x=3+3=6,同時i=5。

    y呢?在同一個運算表達式中兩次++i后,是4+5還是5+5?正確答案是y=5+5=10,i=5。這里加法運算符左右兩邊都是變量x,所以5+5。

 

這個題目看似很簡單,其實可以應發聯想,若y的表達式為:

i=3;
y=(++i)+(++i)+(++i)+(++i);    

這時y的值是多少呢?y=7+7+7+7=28?

正確答案是y=23,i=7。為什么會出現這樣的問題?

不理解這個問題,說明你對c語言運算符的運算規則還沒有透徹的理解。

這里真實的運算規則是

由於加法運算符“+”是二元運算符,所以每次運算都只需要2個操作數,運算后結果保存在一個緩存變量ans中。

所以先運算(++i)+(++i),則結果為ans=5+5=10,i=5;

然后再運算ans+(++i),則結果為ans=10+6=16,i=6;

然后再運算ans+(++i),則結果為ans=16+7=23,i=7;

然后賦值y=ans=23;

看到這里明白了吧,其實結合逆波蘭表達式的堆棧求解方法很容易理解這個問題。

不要誤以為y=(++i)+(++i)+(++i)+(++i)就是單純運算4次自加后,i和i之間的加法。

 

同理思考問題:

i=3;
y=(i++)+(i++)+(i++)+(i++)

 

是不是ans=3+3=6;ans=6+5=11;ans=11+6=17;y=17;?

你可以驗證,發現y=3+3+3+3=12;

這說明這里的4個i++是在y的求職結束之后進行自加的。

這個問題怎么理解?和我們前面的結論有沖突?

其實沒有沖突,真實的原因是你要理解i++和++i發生的准確條件:

對於++i,你完全可以用“(i=+1)”來替換,就是說,遇到++i一定是要先進行自加后才會完成其他的運算操作的。

對於i++,這里的自加,准確的講,是整個逆波蘭表達式操作數堆棧中所有的操作數全部清空后,才對需要自加的操作數自加的。簡單的講就是:忽略所有的i++操作符,先進行運算,等表達式的值求解完成后,才對相應的變量進行自加。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM