5

私は C を初めて使用するので、私のコードに本当に初心者向けのエラーが表示された場合は、しばらくお待ちください。

宿題の一部として、データを保存するために番号付きリストを作成する必要があります。これまでに行ったことは、リストの各ノードを表す構造体を作成することです (firstNode は、リストの最初のノードを指すグローバル変数です)。

typedef struct Node {
    struct Node *next;
    int id;
    int value;
}Node;

Node *firstNode = NULL;

その後、ノードの値をチェックして新しいノードをリストに挿入する関数を作成しました。値が小さいノードは、他のノードの前に配置する必要があります。だから私がしたことはこれでした:

void addNewNode(int nodeId, int nodeValue) {
    Node *newNode = (Node*) malloc(sizeof(Node));
    Node *temp, *tempPrev;
    newNode->id = nodeId;
    newNode->value = nodeValue;

    if(firstNode == NULL) {
        newNode->next = firstNode;
        firstNode = newNode;
    }
    temp = firstNode;
    tempPrev = NULL;
    while(temp->value < newNode->value) {
        tempPrev = temp;
        temp = temp->next;
    }
    if(tempPrev == NULL) {
        newNode->next = firstNode;
        firstNode = newNode;
    } 
    else {
        tempPrev->next = newNode;
        newNode->next = temp;
    }
}

上記のコードの問題は、時々プログラムがクラッシュすることですが、エラーが見つかりません!

また、私が次にやろうとしているのは、いくつかのノードが同じ値を持つ場合、ID に従って並べ替えられることです (ID が小さいノードが最初に来ます)。これどうやってするの?私は本当に混乱しています!

4

5 に答える 5

3

while ループ条件では、temp が NULL に等しいかどうかをチェックしないため、プログラムがクラッシュします。つまり、すでにリスト内にある他のすべてのノードよりも大きな値を持つ新しいノードを挿入しようとすると、temp はリストの最後に到達し (temp は NULL に等しい)、そのノードの値を取得しようとします。 ! したがって、修正は次のようになります。

while(temp!=NULL && temp->value>newNode->value)
{
    ....
}

ノードの ID については、while ループ条件を次のように拡張できます。

while(temp!=NULL && (temp->value<newNode->value || (temp->value==newNode->value && temp->id<newNode->id))
{
    ....
}

また、firstNode が NULL かどうかを確認する最初の if ステートメントは、この場合は必要ありません。NULL の場合、プログラムは while ループに入らず、while ループの後の最初の if ステートメントに直接進みます。

ところで、C の新しいプログラマーのための素敵なコード :-)

于 2010-01-13T13:05:31.033 に答える
1

1.

if(firstNode == NULL) {
        newNode->next = firstNode;
        firstNode = newNode;
        return; // done with inserting the first node...need not continue.
    }

2.

// ensure temp is not null only then access its value.
while(temp && (temp->value < nodeId->value)) {
        tempPrev = temp;
        temp = temp->next;
    }
于 2010-01-13T13:05:17.970 に答える
0

1 つには、そこに nodeID -> 値があります。NodeID は int であるため、これは機能しません。

于 2010-01-13T13:07:17.380 に答える
0

デバッグの方法として、簡単なテスト ハーネスを作成します。つまり、考えられるすべての一般的なシナリオ (ユニット テスト) を実行する、作成したテスト プログラムです。各単体テストは、適切に実行され、期待される出力が生成されることを確認します。このようにして、すべてが正常にチェックされれば、準備完了であると確信できます。単体テストが失敗した場合、何が壊れているかが正確にわかります。

于 2010-01-13T13:08:22.633 に答える
0

境界条件をチェックするいくつかのテスト ケースを作成することをお勧めします (たとえば、空のリストに要素を追加する、既存のリストの先頭に配置する必要がある要素を追加する、リストの最後に配置する要素を追加するなど)。既存のリスト; 既存のリストの途中で終了する必要がある要素を追加します)。リスト内の要素をデバッグのためにコンソールに出力する「印刷」機能を作成します。少なくとも、クラッシュのコンテキストを絞り込むのに役立ちます。1 つの可能性 (何回追加しているのかわかりません) は、プログラムがメモリ不足になり、malloc が失敗することです。必要なメモリの割り当てに失敗した場合、 malloc は NULL を返すと思うので、それを確認できます。

Node *newNode = (Node*) malloc(sizeof(Node)); 
if(newNode == NULL)
{
  printf("Out of Memory!");
  return;
}
于 2010-01-13T13:11:53.023 に答える