4 回答

TA貢獻(xiàn)883條經(jīng)驗(yàn) 獲得超454個(gè)贊
其實(shí)這兩種結(jié)果都有可能出現(xiàn)。
先明確一下關(guān)于運(yùn)算符和操作數(shù)的基本知識:運(yùn)算符需要有操作數(shù)才能構(gòu)成表達(dá)式(比如 a + b 就是一個(gè)加法表達(dá)式,+ 是運(yùn)算符,a 和 b 就是操作數(shù))。而運(yùn)算符表達(dá)式在執(zhí)行時(shí)有一個(gè)“操作數(shù)求值”的過程(也就是確定 a 和 b 的值)。
如果操作數(shù)本身是個(gè)函數(shù)調(diào)用,那么對這個(gè)操作數(shù)求值就是得到函數(shù)的返回值。有一點(diǎn)很重要:函數(shù)中的一些代碼(尤其是 cout << 這樣的IO操作)的行為算是函數(shù)的副作用,這些副作用的發(fā)生并不一定和求值同時(shí)發(fā)生。
關(guān)于表達(dá)式的副作用何時(shí)發(fā)生,C++ 其實(shí)有比較復(fù)雜的序列點(diǎn)規(guī)則。我不打算細(xì)說這個(gè)規(guī)則,后面遇到具體情況時(shí)我會提到它,你目前只需要記住副作用不一定和求值同時(shí)發(fā)生。
那么我用你的這個(gè)例子具體說明一下:
cout<<x.f1()<<x.f2() 這是一個(gè)復(fù)合表達(dá)式。
對其中的?cout << x.f1() 這個(gè)子表達(dá)式來說?x.f1() 是右操作數(shù),這個(gè)右操作數(shù)是個(gè)函數(shù)調(diào)用。
而 << 其實(shí)也是函數(shù)調(diào)用,這是重載 << 運(yùn)算符函數(shù)。x.f1() 其實(shí)算是 << 函數(shù)的參數(shù)。
cout<<x.f1()<<x.f2() 其實(shí)是連續(xù)兩次 << 調(diào)用,并且是?<<x.f1() 在前,<<x.f2() 在后(運(yùn)算符的優(yōu)先級決定的)。也就是說一定是先調(diào)用了 << 5,再調(diào)用 << 3,所以最后結(jié)果是 53(5在3之前)。
至于讓你疑惑的那部份輸出:C++ 的求值和序列點(diǎn)規(guī)則說“參數(shù)的副作用要在函數(shù)執(zhí)行前發(fā)生”。注意:只是在之前發(fā)生即可。
所以完全有可能 f1() 和 f2() 的副作用(也就是輸出"f1: m = 5"和"f2: m = 3")在兩次 << 函數(shù)調(diào)用前就已經(jīng)發(fā)生了。加之 C++ 沒有規(guī)定參數(shù)副作用誰先誰后,所以"f2: m = 3"先輸出是有可能的。
====以上就是關(guān)于你看到的這個(gè)結(jié)果的解釋====
下面我想多說下:
我不知道你用的編譯環(huán)境是什么? 編譯器遵循的是哪個(gè)標(biāo)準(zhǔn)?
實(shí)際上如果你用的編譯器支持的 C++ 標(biāo)準(zhǔn)夠新的話(C++17),f1: m = 5 和 5 是會先輸出的。
這是因?yàn)樵?C++17 標(biāo)準(zhǔn)中增加了一些序列點(diǎn)規(guī)則,導(dǎo)致這個(gè)代碼的行為不再是不確定的,而是保證會先輸出?f1: m = 5 和 5。
(我有些好奇不同編譯器在各個(gè)標(biāo)準(zhǔn)下的行為,希望能告知我你用的編譯環(huán)境是什么)
最后,你知道你其實(shí)根本就沒用到 X 的成員變量 m 吧...

TA貢獻(xiàn)168條經(jīng)驗(yàn) 獲得超109個(gè)贊
cout是先從右到左分別運(yùn)行函數(shù)f2(),f1(),然后再輸出兩個(gè)函數(shù)的return返回值,謝謝采納

TA貢獻(xiàn)8條經(jīng)驗(yàn) 獲得超2個(gè)贊
cout輸出將輸出先像壓棧一樣保存在緩沖區(qū),在進(jìn)行輸出,所以是先運(yùn)行右邊再左邊
- 4 回答
- 1 關(guān)注
- 1787 瀏覽
添加回答
舉報(bào)