2014-09-24 52 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