最近看到了一道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++操作符,先進行運算,等表達式的值求解完成後,才對相應的變量進行自加。