与赋值表达式的C ++比较是右侧表达式

时间:2013-10-30 16:56:06

标签: c++ data-structures

我目前正在处理使用C ++的数据结构问题。 我将检查单链表中的节点是否按升序排序。这里有我的代码的一些细节

Node.cpp

class Node
{
   public:
     double data;       
     Node* next;    
};

对于出现问题的部分,

double preValue = sLL.head->data;       
Node *curNode = sLL.head->next;     

    do
    {
        if (preValue > (preValue = curNode->data))  // Problem occur in this line   
            return false;
    }while (curNode = curNode->next);

作为'>'的评估顺序运算符正在评估左侧表达式,然后是右侧表达式

赋值运算符将返回左值的引用。

因此,preValue > (preValue = curNode->data)应比较最后一个节点和当前节点,并在完成比较后分配下一个节点的数据。因此,我认为我的实施应该是有效的。

但是,if(preValue > (preValue = curNode->data))的结果超出了我的预期,当比较preValue大于新preValue时,它会一直返回false。

我试图打印出if语句的返回值,只要左表达式大于或小于右表达式,它总是返回0。 我不明白为什么会这样。谁能告诉我我犯了什么错误?

P.S。该程序可以正常使用以下实现

double preValue = list.head->data;      
Node *curNode = list.head->next;            

do
{
    if (preValue > curNode->data)       // Check ascending order
        return false;

    preValue = curNode->data;

}while (curNode = curNode->next);       

2 个答案:

答案 0 :(得分:3)

这一行是未定义的行为:

if (preValue > (preValue = curNode->data))  // Problem occur in this line

因为您要分配给变量(preValue)并从同一个变量读取,而读取不用于确定写入的值

来自C ++03§5/ 4 [expr]

  

[...]之间的比较   和下一个序列点标量对象的评估值最多只能修改一次   一个表达。此外,只能访问先前值以确定要存储的值。   对于完整的子表达式的每个允许排序,应满足本段的要求   表达;否则行为未定义。

序列点出现在完整表达式(即以分号结尾的表达式或语句)之后,以及&&||,{{的第一个操作数之后。 1}}和?:运算符。所有其他运算符(包括,运算符) not 在其参数的求值之间具有序列点。序列点也出现在与此问题无关的其他几个地方。

正如你所说,修复只是将它拆开,以便在比较的单独声明中进行赋值。

当我使用带有>编译器标志的GCC编译此代码时,我收到此警告:

-Wall

我强烈建议您始终使用warning: operation on ‘preValue’ may be undefined [-Wsequence-point] -Wall进行编译,以便编译器立即标记这些错误,您可以更正它们。

答案 1 :(得分:0)

这一行

if (preValue > (preValue = curNode->data)) 

是未定义的行为。请参阅sequence points的概念。表达式只能在两个序列点和'>'之间修改其对象一次不是序列点。

相关问题