2011-10-01 241 views
3

我剛剛讀過評估順序和運算符優先級是C++中不同但相關的概念。但我還不清楚這些是如何不同但相關?表達式評估順序

int x = c + a * b; // 31 
int y = (c + a) * b; // 36 

上述說明與評估順序有什麼關係。例如,當我說(c + a)上午我改變其優先順序來改變表達式評估的順序?

回答

6

關於評估順序的重要部分是任何組件是否有副作用。

假設你有這樣的:

int i = c() + a() * b(); 

ab有副作用:

int global = 1; 

int a() { 
    return global++; 
} 
int b() { 
    return ++global; 
} 
int c() { 
    return global * 2; 
} 

編譯器可以選擇什麼樣的順序調用a()b()c(),然後將結果插入表達方式。此時,優先級接管並決定運用哪個命令來應用+*運算符。

在本例中的最可能的結果要麼是

  1. 編譯器將評估c()第一,其次a()然後b(),導致i = 2 + 1 * 3 = 5
  2. 編譯器將評估b()第一,其次是a()和然後c(),導致i = 6 + 2 * 2 = 10

但編譯器可以自由選擇wh atever命令它想要的。

的短篇小說是優先告訴你在哪個運營商的應用參數(*+之前)的順序,而爲了評估的告訴你在什麼樣的順序參數都解決了(a()b()c() )。這就是爲什麼他們「不同但相關」。

0

答案可能會也可能不會。

a,b和c的評估順序取決於編譯器對此公式的解釋。

+1

正如其他人所說,評估順序不同於優先規則。 – dp2

3

「評價順序」是指當相同表達式中的不同子表達相對於彼此被計算時。

例如在

3 * f(x) + 2 * g(x, y) 

你有乘法和加法之間通常的優先級規則。但是我們有一個評估問題的順序:第一個乘法會在第一個乘法之前的第二個還是第二個之前發生?這很重要,因爲如果f()具有改變y的副作用,則整個表達式的結果將根據操作的順序而不同。

您的具體示例中,不會出現此評估方案的順序(其中結果值取決於順序)。

1

只要我們談論內置操作員:不,您不會通過使用()來更改評估順序。您無法控制評估順序。事實上,這裏根本沒有「評估順序」。

只要結果正確,編譯器就可以以任何期望的方式評估該表達式。甚至不需要使用加法和乘法運算來評估這些表達式。添加和乘法只存在於程序的文本中。編譯器完全可以完全忽略這些特定的操作。在某些硬件平臺上,這樣的表達式可能由一個原子機器操作來評估。出於這個原因,「評估順序」的概念在這裏沒有任何意義。沒有什麼可以應用「訂單」的概念。

您使用()更改的唯一內容就是表達式的數學含義。假設a,bc都是2a + b * c必須評估爲6,而(a + b) * c必須評估爲8。而已。這是唯一保證給你的結果:結果是正確的。如何獲得這些結果是完全未知的。只要結果正確,編譯器可以使用絕對的任何東西,任何方法和任何「評估順序」。

另一個例子,如果你在你的程序這兩個公式如下相互

int x = c + a * b; 
int y = (c + a) * b; 

編譯器可以自由地評價其

int x = c + a * b; 
int y = c * b + x - c; 

這也將產生正確的結果(假定沒有溢出相關的問題)。在這種情況下,實際的評估計劃甚至不會看起來像您在源代碼中寫的東西。

簡而言之,假設實際評估與您程序源代碼中所寫內容的任何顯着相似性都是天真的。儘管人們普遍認爲,內置的操作員通常不會被翻譯成他們的機器「同行」。

以上內容適用於內置的操作員。一旦我們開始處理超載的操作員,事情就會發生巨大的變化。確實根據表達式的語義結構評估了重載操作符。即使對於重載操作員也有一些自由,但它不像內置操作員那樣不受限制。

0

考慮下面的例子:

#include <limits.h> 
#include <stdio.h> 
int main(void) 
{ 
    double a = 1 + UINT_MAX + 1.0; 
    double b = 1 + 1.0 + UINT_MAX; 
    printf("a=%g\n", a); 
    printf("b=%g\n", b); 
    return 0; 
} 
在數學方面

這裏,因爲我們知道,A和B都被平等計算,並且必須有同樣的結果。但是在C(++)世界中,這是真的嗎?查看程序的輸出。

+0

這是真的......但是'a'和'b'的值的差異與積分促銷規則而不是評估順序有關。 – YSC

+0

@YSC訂單決定轉換/促銷。 –

0

我想介紹一下a link這個問題。 規則3和4提到約sequence point,另一個值得記住的概念。