后缀否定是不正确的,而且是交流性的

Postfix negative is incorrect and communative

本文关键字:不正确 后缀      更新时间:2023-10-16

所以我使用堆栈来评估Postfix表达式。表达式10 6 -读作10 - 6中缀并且应该等于4。但事实并非如此,它等于-4。更糟糕的是,即使我试图反转代码,它仍然等于-4。我不确定这是否是我的堆栈、函数调用或C++的一些怪癖出了问题。然而,如果我将堆栈中的1个弹出值存储在一个变量中,然后执行等式,它会很好地工作。

相关代码:堆栈类

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

是的,这是"C++的怪癖":这个特定表达式中参数的求值顺序是未定义的。奇怪的是,你两次都得到相同的结果,但你通常不应该假设这些pop是从左到右评估的!

从链接的文章,部分"隐藏的相关性":

x=f()+g()+h();

对会发生什么有任何疑问吗?在乍一看,这里似乎没有什么问题。3函数将以不确定的顺序调用,其返回值的总和将计算值并执行赋值。但是如果所有3个函数都访问共享的静态或全局他们读取和修改的变量?我们不知道将调用3个函数,因此我们在中不知道对共享数据的读写访问顺序是执行。再一次,另一个序列点挑战。

解决方案:使用临时变量。

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

问题是两个pop操作之间没有序列点。这意味着编译器可以自由地按照它想要的任何顺序执行这些操作。编译器可能会选择先执行第二个stack.pop(),因为它更容易。你需要确保有一个序列点。最简单的方法是使用分号:

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

除了分号之外,还有其他东西可以强制执行特定的操作顺序。例如,您可以非常巧妙地使用逗号运算符或三元运算符。不要那样做。只需进行显而易见的思考,并将至少一个数字放入局部变量中。