標籤:

關於C語言中自增自減的問題?

問題是這樣的,有同學問我一道關於c語言中自增自減的問題,在沒有編譯前進行分析,然後編譯運行後就哭了,我算的結果是:

4 2

6 1

5 3

4 2

2 2

4 2

運行後錯了4個結果,在百度上搜了一圈,全沒有說清楚,還請大神幫助解答,附圖片和源代碼,注釋的是測試用的.

#include &

int main(int argc, char* argv[]) {
int x,y = 3;
//x = (y++)+(--y)+(--y);
//x = (y++);
//x = (y++) + (--y);
x = (y++) + (--y) + (--y);
//x = (--y) + (--y);
printf("%d %d
",x,y);

y = 3;
x = 3+(--y)+(--y);
printf("%d %d
",x,y);

y = 3;
x = (y++)+(--y);
printf("%d %d
",x,y);

y = 3;
x = 2+(--y);
printf("%d %d
",x,y);

y = 3;
x = (--y);
printf("%d %d
",x,y);
x = x+(y++)+(--y);
printf("%d %d
",x,y);

return 0;
}


寫出這樣代碼的人要被彈JJ彈到死。

==

===

挖擦,微軟大法好啊!又多了種不同答案!

(Codeforces Custom Invocation)

===

問問你們老師,這&仨&四個編譯器誰死?!

===

clang++ 和 g++ 已經給出了未定義行為的提示了。


如果不是考二級,那麼請放棄這種無謂的探索,並遠離這個老師。


error:fuck the damn code and tanhaoqiang


C語言中有一個叫序列點(sequence point)的東西。

在程序中,表達式可能會對系統環境做出改變,這樣的改變被稱為副作用(side effect),例如輸入輸出流、變數修改之類的操作。

在程序的執行期間有一些點,這些點中,一個特定的表達式所有副作用都會完成,而下一個表達式的副作用尚未發生,程序中這樣的點被稱為序列點。在兩個連續的序列點之間,可以用任何次序做局部的計算。作為一名程序猿,你不應當在兩個序列點之間多次修改同一個對象。例如:

i = i++; // 錯,賦值和遞增運算可能會以任何次序進行,i 的值執行結束後無法預料

作為一名程序猿,要始終記住,你寫的程序除了給機器看,還要給人看。


無定義行為,

這種代碼本身就是錯誤的。

很多初學者以為能編譯通過的代碼就沒有語法錯誤,

是被垃圾書所誤導。

能編譯通過的不一定是正確(語法)的代碼。

參見:

「牙里長嘴」和「a+=a-=a*a」


把譚浩強的那本C語言教程給扔了吧。

工作後沒人研究這玩意,即便你研究透了,你在工作項目中這樣「炫技」的話,十有八九要被經理同事批……

原則上不要在一個語句中多次操作一個變數。


貌似編程的宗旨是把人腦從這種無謂的推理中解放出來的吧

ps. 我看到了360的存在


一條語句中對同一變數進行多次操作,語言規範中沒有規定計算順序,因而編譯器可以自己選擇實現方法。這就允許不同編譯器有不同實現,有的從做到右算,有的從右到左算,有的從中間向兩端算.....


好像有的編譯器是從左向右組合,有的是從右向左,所以會出現不同的答案吧。


推薦閱讀:

學習 Python 用哪本書好?
MATLAB 有什麼奇技淫巧?
為什麼都2015年了,學校裡面的開發還是用vc6?
樹莓派做集群的意義?
如何評價 MATLAB R2016b ?

TAG:編程 | CC |