1

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

节点.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大于 new的 a 时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);       
4

2 回答 2

3

这一行是未定义的行为:

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编译器立即标记这些错误并且您可以更正它们。

于 2013-10-30T17:00:45.767 回答
0

这条线

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

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

于 2013-10-30T17:03:26.983 回答