2

私はリンクされたリストを C で実装することに取り組んできました。私は、Nick Parlante の「Linked List Basics」を解決して取り組んでいます。

機能: リンクされたリストの最後に要素を挿入する

私は実装上の問題に出くわし、回避策を構築することができました: LList で "EndPointer" を使用する場合、return 関数を使用して関数の EndPointer を設定し、新しい ReferencePointer を引き渡してから main 内で変更することができます。

コード - 正常に動作しますが、回避策:

// within main
lastPtrRef = _pushEnd(lastPtrRef, i);

// == function: push to end
node** _pushEnd(node **endRef, int value)
{
    // 1) allocate stack mem / make room for new element
    node *newNode = malloc(sizeof(node));

    // do the data work
    newNode->value = value;

    // 2) make  element point to NULL (fo beeing the new last element
    newNode->next = NULL;

    // 3) make old last element point to new element
    *endRef = newNode;

    return &(newNode->next); // more readable then vers. below
    // this returns the mem address only of the pointer of the node!!!
    //return (&((*endRef)->next));

}

================================================== ============================

これは、関数内ですべての作業を行っている限りですが、実際には機能しません。私が得ていない点についてのヒントはありますか?!

void _pushEnd(node **endRef, int value)
{
// 1) allocate stack mem / make room for new element
node *newNode = malloc(sizeof(node));

// do the data work
newNode->value = value;

// 2) make  element point to NULL (fo beeing the new last element
newNode->next = NULL;

// 3) make old last element point to new element
*endRef = newNode;

}

ポインターの内容を最後の要素 (スコープ内: メイン) に実際に変更するには、参照ポインターへのポインターが実際に必要になる可能性があるため、現在はローカル変数 "endRef" のみを変更しているように見えます。中身じゃない!?

どんな助けでも大歓迎です...


編集: アイデアは、LList の先頭にダミー ノードを使用せずに追加することです。

私の構造体は次のようになります:

typedef struct node     {
int     value;
struct node *next;      } node;

メイン - ローカル変数 (スタック):

node *head = NULL;
node **lastPtrRef = &head;

編集:ほとんどの命題はとにかくrefPointerを返すことになりました。しかし、refPointer への refPointer をもう 1 つ必要としないため、それはそれほど悪いアイデアではないかもしれません。

あなたのすべての助けと多くの有用なコメントに感謝します!

4

4 に答える 4

3
*endRef = newNode;

その前に、古いendRef->next点を指摘するnewNode必要があります。

if (*endRef)
    (*endRef)->next = newNode;

*endRef = newNode;
于 2013-02-23T11:42:02.700 に答える
3

_pushEndポインタがどこに格納されているかという、すでにわかっているmainことを示しています。main

次のような多くのオプションがあります。

  • pushEnd は node* (node** ではない) を取得し、新しいポインターを返し、main はそれを変数に格納します。

  • pushEnd は node** を取得し、main の値をそれ自体で上書きします。何も返す必要はありません。

編集:

ポイント 1 の例:

node* pushEnd(node* end, int entry); // returns new end.
int main() {
    node* end = newlist();
    int i=0;for(;i<10;++i) {
        end = pushEnd(end, i);
    }
}

ポイント 2 の例:

void pushEnd(node** ptrToEnd, int entry); // changes *ptrToEnd
int main() {
    node* end = newlist();
    int i=0;for(;i<10;++i) {
        pushEnd(&end, i);
    }
}
于 2013-02-23T11:43:12.697 に答える
1
struct node {
   struct node *next;
   int value;
   };

struct node *root = NULL
   , **lastPtrRef = &root;

 // within main
lastPtrRef = pushEnd(lastPtrRef, i);

//function: push to end; return new pointer to tail->next

struct node  **pushEnd(struct node **p, int value)
{
    struct node *p;

    // 0) is it really the end ?    
    while (*pp) {pp = &(*pp)->next; }

    // 1) allocate
    p = malloc(sizeof *p);

    // do the data work
    p->value = value;

    // 2) make  element point to NULL (fo beeing the new last element
    p->next = NULL;

    // 3) make old last element point to new element
    *pp = p;

    return &p->next;

}

または、p 変数は不要なので削除します。

struct node  **pushEnd(struct node **p, int value)
{

    while (*pp) {pp = &(*pp)->next; }

    *pp = malloc(sizeof **pp);
    (*pp)->value = value;
    (*pp)->next = NULL;

    return &(*pp)->next;

}
于 2013-02-23T13:28:16.437 に答える
1

あなたの問題はリターンの行にあると思います:

return (&((*endRef)->next));

これまでに行ったように*endRef = newNode;、作成したばかりのノードの次の要素の方向を返します。

于 2013-02-23T11:42:27.617 に答える