2
void addNewNode (struct node *head, int n)
{
    struct node* temp = (struct node*) malloc(sizeof(struct node));
    temp -> data = n;
    temp -> link = head;
    head = temp;
}

上記のコードは、リンクされたリストの先頭に新しいノードを追加するための一般的に間違ったバージョンの関数です。一般的に、正しいバージョンは次のようになります。

void addNewNode (struct node **head, int n);
void addNewNode (struct node * &head, int n);

うまく機能する目的のために、別の単純な関数を作成しました。

struct node* addNewNode (struct node *head, int n)
{
    struct node* temp = (struct node*) malloc(sizeof(struct node));
    temp -> data = n;
    temp -> link = head;
    return temp;
}

しかし、これがコードやチュートリアルで使用または議論されているのを見たことがないので、このアプローチに何らかの欠陥があるかどうか知りたい.

4

6 に答える 6

17

欠点は、リストへのヘッド ポインターを更新する最後の手順を実行する呼び出し元に依存していることです。

呼び出し元がこれを怠った場合、コンパイラは文句を言わず、すべての意図と目的のために、リストは変更されていないように見えます (ノードのメモリがリークされます)。

于 2008-11-02T19:49:26.720 に答える
4

これは、リンクされたリストがほとんどの関数型言語でどのように機能するかです。たとえば、ML では次のようにします。

val ls = [1, 2, 3, 4]
val newList = 0 :: ls

::構文は、実際には 2 つのパラメーター ( と ) を取り、0最初の要素としてls持つ新しいリストを返す関数です。0ML のリストは実際にはリスト ノードとして定義されているため、実際には提案::した関数と非常によく似た記述になっています。addNewNode

つまり、おめでとう、C で不変の連結リストの実装を作成しました! これを理解することは、実際には関数型言語への非常に重要な最初のステップであるため、知っておくことは本当に良いことです。

于 2008-11-02T19:50:33.503 に答える
2

addNodeあなたのアプローチは、オブジェクト指向言語でより一般的に使用されるリストのメソッドであるという考えと互換性がありません。

個人的に私は思います

list.add(element)

よりもはるかに直感的です

list = add(list, element)

数十の「コレクション」ライブラリが間違っていることはありません...

于 2008-11-02T19:50:33.177 に答える
1

Afaik, それがglibのリストの仕組みであり、gtkの人々がその方法を使用した最初の方法ではなかったと確信しているので、私はそれを新しいアプローチとは呼びません. 個人的には、ノード カウント、ファースト ポインター、ラスト ポインターを保持する基本構造を持つことを好みます。

于 2008-11-03T15:56:23.053 に答える
1

これは新しいことではありません。quinmars が指摘したように、glib は 10 年以上にわたってこのようにしてきました。それは素晴らしいアイデアですので、それを理解しておめでとうございます.

ただし、コードに関する 1 つの問題: malloc()C で の戻り値をキャストしないでください。また、 を使用して型名を繰り返さないでくださいsizeof。割り当て行は次のようになります。

struct node* temp = malloc(sizeof *temp);

見る?より短く、よりタイトに、より読みやすく、台無しになりにくくなります。より良い!:)

于 2008-11-03T16:10:35.803 に答える
0

上記の正しいコードのいずれにも問題はありません。ヘッドを変更するかどうかは設計の問題であり、変更されたリストを返す方法です。OOP が使用される例として、std::list<> に適切なインターフェイスが実装されています。このようなアプローチには潜在的な問題はありません。ヘッド ポインターは非表示であり、必要に応じて変更できます。また、呼び出し元はヘッドを明示的に格納しないため、リストへの参照は常に正しいです。

(C ではなく C++ を使用する場合) 見苦しくなるのは、malloc です。'new' を使用することをお勧めします。

于 2008-11-02T19:50:18.060 に答える