繁体   English   中英

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

[英]C++ comparison with an assignment expression be the right hand side expression

我目前正在处理使用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。 我不明白为什么会这样。 谁能告诉我我犯了什么错误?

ps该程序可以正常使用以下实现

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);       

这一行是未定义的行为:

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

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

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

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

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

正如您所说,修复方法是将其拆分,以便赋值在比较的单独语句中进行。

当我使用-Wall编译器标志使用GCC编译此代码时,我收到此警告:

warning: operation on ‘preValue’ may be undefined [-Wsequence-point]

我强烈建议您始终使用-Wall-Werror编译,以便编译器立即标记这些错误,您可以更正它们。

这条线

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

是一种未定义的行为。 请参阅序列点的概念。 表达式只能在两个序列点之间修改其对象一次,而“>”不是序列点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM