2014-09-24 54 views
1

所以我正在評估Postfix表達式使用堆棧。表達式10 6 -的讀數爲10 - 6中綴,應該等於4。但它不,它等於-4。更糟的是,即使我嘗試反轉代碼,它仍然等於-4。我不確定這是否是我的堆棧或函數調用錯誤,或者C++的一些怪癖。但是,如果我將一個彈出的值從堆棧中存儲到一個變量中,然後執行該等式,則可以正常工作。Postfix負面是不正確和通信

相關代碼: Stack類

template <class Item> 
class stack { 
private: 
    struct node { 
     Item item; 
     node* next; 
     node(Item x, node* t) { 
      item = x; 
      next = t; 
     } 
    }; 
    typedef node* link; 
    link head; 

public: 
    stack(int) { head = 0; } 
    int empty() const { return head == 0; } 
    void push(Item x) { head = new node(x, head); } 
    Item pop() { 
     Item v = head->item; 
     link t = head->next; 
     delete head; 
     head = t; 
     return v; 
    } 
}; 

Evalutating the negative operation 

    else if (argv[i][0] == '-') { 
    stck.push(((-1) * stck.pop()) + stck.pop()); // A-B = -B+A 
    // stck.push(stck.pop()+((-1)*stck.pop())); //A-B = -B+A 
} // Both equations equal the same thing (Note I dont use both at the same 
    // time) 

這工作

int n = (stck.pop()); 
stck.push(-1*n+stck.pop()); //A-B = -B+A 
+0

'pop' return和'Item',Item的'operator *'的實現是什麼,至少是?它更好[MCVE](http://stackoverflow.com/help/mcve) – NetVipeC 2014-09-24 16:18:51

回答

2

是的,這是一個"quirk of C++",即:在這個特定的表達參數的計算順序是不確定的。這很奇怪,你如何得到相同的結果兩次,但你通常不應該假設這些彈出被評估從左到右!

從鏈接的文章,章節 「隱藏相關性」:

X = F()+ G()+ H();

有什麼疑問會發生什麼?在 第一眼看來,似乎這裏沒有什麼可能出錯。函數將以不確定的順序調用,它們的返回值 的總和將被計算並且將執行分配。但是, 如果所有3個函數都會訪問它們讀取和修改的共享靜態或全局變量 會怎麼樣?我們不知道將以何種順序調用3個函數,因此我們不知道 哪個讀取和寫入訪問共享數據的順序是 。再次,另一個序列點挑戰。

解決方案:使用臨時變量。

0

stck.push(((-1) * stck.pop()) + stck.pop());

的問題是,這兩個彈出操作之間沒有順序點。這意味着編譯器可以根據需要隨意執行這些操作。編譯器可能會首先選擇第二個stack.pop(),因爲它更容易。你需要確保有一個序列點。要做到這一點,最簡單的方法是使用一個分號:

subtrahend = stck.pop(); 
stck.push (stck.pop() - subtrahend); 

有除了一個分號,可以強制操作的特定順序其他的事情。例如,你可以用逗號運算符或三元運算符非常聰明。不要這樣做。只要做明顯的想法,並把至少一個數字放在一個局部變量中。

+0

-1我剛剛在15分鐘前發佈了確切的答案! – BeyelerStudios 2014-09-24 16:45:11