我有以下代碼。這個輸出的原因是什麼?
int x=80;
int &y=x;
x++;
cout<<x<<" "<<--y;
輸出結果是80 80.我不明白怎麼回事。我認爲x的輸出是81,但我對y沒有任何瞭解。參考變量如何受減量運算符影響。有人可以解釋嗎?
我有以下代碼。這個輸出的原因是什麼?
int x=80;
int &y=x;
x++;
cout<<x<<" "<<--y;
輸出結果是80 80.我不明白怎麼回事。我認爲x的輸出是81,但我對y沒有任何瞭解。參考變量如何受減量運算符影響。有人可以解釋嗎?
關於重定向操作符<<
的一個令人討厭的事情是,它們直觀地傳達了確實不存在的「順序計算」的缺陷。
當你寫
std::cout << f() << g() << std::endl;
的輸出將首先顯示的f()
結果,然後g()
的結果,而是g()
實際調用可以調用f()
之前發生。
它甚至會比這更糟糕......這不是該序列是不可預測的,但確實序列的概念本身是無效的。在
std::cout << f(g()) << h(i()) << std::endl;
它例如法律的第一個函數被調用爲g()
,其次爲i()
,其次是h()
最後由f()
。甚至不保證所有調用的順序都是相同的(不是因爲編譯器製造商喜歡嘲笑你,而是因爲代碼可以內聯,並且如果包含函數在不同的上下文中內聯,編譯器可以決定不同的順序)。
唯一C++運算符,在所述評價順序保證的序列是:
&&
:首先評估左側且僅當結果爲「真」的計算結果的右側||
:首先評估只有在結果爲「假」時評估右側?:
:首先評估條件,然後僅評估第二或第三個操作數,
:逗號運算符...評估左側,丟棄該值,然後評估並返回右側。注:函數參數之間的逗號不是逗號運算符,也不會執行評估命令。而且這guaratee只針對預定義的運算符有效。如果您的班級中存在&&
,||
或,
,他們只是普通的操作員,對評估順序沒有任何特殊限制。
任何其他運營商不徵收評估順序任何限制,這包括<<
即便利用某種技巧,你以爲。
計算表達式爲:
((cout << x) << " ") << --y;
有左手側的評估和表達式的右手側時,編譯器可以輸出代碼之間沒有序列點(或排序)作爲第一步評估--y
。
由於y
是x
這裏的參考,這是因爲你無論從閱讀和中間沒有順序點在同一個表達式寫入x
實際上未定義的行爲。
請檢查編輯的代碼這肯定與指針算術有關。當我們說y有一個地址x即80,並嘗試和減少y時,它也不會在我的系統上遞減。 –
@SanyamGoel:這是未定義的行爲。不同的編譯器可以(也將會)輸出不同的東西。 LHS和RHS的評估順序是實現定義的,加上對'x'的讀取和寫入,沒有順序點=>未定義的行爲(即它不是合適的C++,它可以做任何事情)。 – Mat
建議編輯:*「請參閱[本SO線程](http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points)的詳細解釋。「* – jrok
這是未定義的行爲,C/C++標準沒有定義該參數的方式被壓入堆棧,和通常的說法是按相反的順序這裏推動時,例如:
func(1, 2)
將被評估喜歡的東西:
push 2
push 1
call func
所以你的情況,--y
進行評估,並推動x
不前。正是在這個例子清楚:
#include <iostream>
int a() { std::cout << "a" << std::endl ; return 1; }
int b() { std::cout << "b" << std::endl ; return 2; }
int main(void) {
std::cout << a() << " " << b() << std::endl;
return 0;
}
從第一次看
,它應該打印:
a
b
1 2
但它打印:
b
a
1 2
x++
增量X併產生作爲表達式的結果是x的原始值。
特別是,對於x ++,沒有時間順序暗示增加和產生x的原始值。編譯器可以自由發出產生x的原始值的機器碼,例如,它可能出現在某個寄存器中,並且延遲增量直到表達式結束(下一個序列點)。雖然x++
似乎增加x到,它不會直到打印。根據--y
,它將獲得增加的值(81)並在打印之前將其減少,因爲它是前綴運算符。
也許這個問題應該有助於澄清你:什麼是C++指針變量和引用變量之間的區別是什麼? (http://stackoverflow.com/questions/57483/what-are-the-differences-between-pointer-variable-and-reference-variable-in-c) – yasouser
這類似於(到http://stackoverflow.com /問題/ 18426473 /預增 - 不工作,AS-I-期望/ 18426505#18426505)。 你缺少一個序列點。 –