1

現在、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)最後のノードと現在のノードを比較し、比較が完了した後に次のノードのデータを割り当てる必要があります。したがって、私の実装は有効であるべきだと思います。

ただし、 の結果は予想外です。 new よりも大きいif(preValue > (preValue = curNode->data))a を比較すると、常に false が返されます。preValuepreValue

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]:

[...] 前のシーケンス ポイントと次のシーケンス ポイントの間で、スカラー オブジェクトの格納値は、式の評価によって最大 1 回変更されます。さらに、以前の値は、保存する値を決定するためにのみアクセスされます。この段落の要件は、完全な式の部分式の許容される順序ごとに満たされるものとします。それ以外の場合、動作は未定義です。

シーケンスポイントは、完全な式 (つまり、セミコロンで終了する式またはステートメント) の後、および、、、、演算子の最初のオペランドの後に&&発生し||ます。他のすべての演算子 (演算子を含む)には、引数の評価の間にシーケンス ポイントがありません。シーケンス ポイントは、この質問に関係のない他のいくつかの場所でも発生します。?:,>

あなたが言ったように、修正はそれをバラバラにして、代入が比較とは別のステートメントで行われるようにすることです。

コンパイラ フラグを指定して GCC でこのコードをコンパイルすると、次の-Wall警告が表示されます。

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

これらのエラーがコンパイラによってすぐにフラグされ、修正できるように、常に-Walland を使用してコンパイルすることを強くお勧めします。-Werror

于 2013-10-30T17:00:45.767 に答える
0

この行

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

未定義の動作です。シーケンス ポイントの概念を参照してください。式は、そのオブジェクトを 2 つのシーケンス ポイント間で 1 回だけ変更できます。「>」はシーケンス ポイントではありません。

于 2013-10-30T17:03:26.983 に答える