2014-09-25 58 views
0

我想了解括號影響表達式中的優先級:爲什麼表達式*(b ++)不首先評估b ++?

int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
auto b = arr; 
std::cout << *(++b) << std::endl; 

// output : 1 

在這段代碼中,我得到預期的輸出,但如果我將其更改爲:

std::cout << *(b++) << std::endl; 
// output 0 

我得到0作爲輸出。由於括號,我會先評估b++,然後再進行解引用。看來我錯了,於是我完全刪除了括號,並用*++b*b++進行了測試,並得到了相同的結果。這意味着括號不會影響這種表達式的優先級嗎?爲什麼這是兩個表達式的結果是equivelant:

*(b + 1) 
*(++b) 

但它不是與*(b++)的情況?

+6

因爲這幾乎是後綴增量的*定義*請解釋你認爲它應該做什麼以及與前綴增量('++ b')有什麼不同。 – delnan 2014-09-25 10:39:36

+0

tl; dr'b ++ == b',圓括號不會奇蹟般地改變評估結果。 – user657267 2014-09-25 10:41:47

+0

@delnan是啊我意識到不同之處,但那是我關心的括號。 – 2014-09-25 10:43:56

回答

7

確實首先評估b++b++增量b並返回前面的b,之前增量發生了。之後的b++b的值的結果是不同的。把它看成是(使用int,而不是int *因爲引用到指針使得簽名醜):(除使用增加值before the next sequence point是不確定的行爲)

int postfix_increment(int &x) { 
    int result = x; 
    x = x + 1; 
    return result; 
} 

如果引入作爲括號結果的臨時變量,爲了確保首先評估它,可能更容易發現差異:

int *tmp = b++; 
// At this point, b == tmp + 1! 
std::cout << *tmp << std::endl; 
+0

okey它說得很清楚。順便說一句,我猜你在tmp中缺少'*' – 2014-09-25 10:50:02

+0

@ Selman22是的,錯過了'b'是一個指針,而不是int。幸運的是,解釋完全沒有區別。 – delnan 2014-09-25 10:51:35

0

*(b+1)工作,因爲你做數學。數學考慮括號。只有在數學完成後,表達式纔會被評估。

​​因爲您在評估之前遞增(前綴增量)。

*(b++)不起作用,因爲您在評估後增加(後綴增量)。

1

*(b++)相當於存儲舊指針,遞增指針和解除引用舊指針

int* post_increment(int* b) 
{ 
    int* old = b; 
    ++b; 
    return old; 
} 

它是一種有益的練習寫圍繞一個普通的指針的薄迭代包裝。在編寫用戶定義的迭代器時,通常會將上面的post_increment()函數編寫爲過載的operator++(int)int的論點純粹是爲了區分它與預增加運算符operator++()。另外,您需要重載operator*()來取消引用迭代器。

相關問題