2016-04-05 24 views
0

参照によってポインタを渡すためのエントリが見つかりましたが、実際にそれらを理解できませんでした。Cポインタを参照渡し?

リンクリストにノードを挿入するためにこの関数を記述しました。関数内で動作するように見えますが、linkedListポインタの変更はmain関数のポインタの後ろには影響しません。簡単な修正はありますか?教室の例では、linkedListポインタがグローバルに宣言されていますが、複数のリンクされたリストを作成できるように、ポインタを渡すことをお勧めします。

void insert(node* linkedList, int value) 
{ 
    node* newNode = malloc(sizeof(node)); 

    if (newNode == NULL) 
    { 
     // failed to make node 
     printf("Failed to insert new node!\n"); 
     return; 
    } 

    newNode->n = value; 

    printf("\n"); 
    printf("Before insert: \n"); 
    printf("\n"); 

    printf("linkedList ptr : %p\n", linkedList); 
    printf("linkedList->n : %i\n", linkedList->n); 
    printf("LinkedList->next : %p\n", linkedList->next); 

    printf("\n"); 
    printf("newNode ptr : %p\n", newNode); 
    printf("newNode->n : %i\n", newNode->n); 
    printf("newNode->next : %p\n", newNode->next); 

    newNode->next = linkedList; 
    linkedList = newNode; 

    printf("\n"); 
    printf("After insert: \n"); 
    printf("\n"); 

    printf("linkedList ptr : %p\n", linkedList); 
    printf("linkedList->n : %i\n", linkedList->n); 
    printf("LinkedList->next : %p\n", linkedList->next); 

    printf("\n"); 
    printf("newNode ptr : %p\n", newNode); 
    printf("newNode->n : %i\n", newNode->n); 
    printf("newNode->next : %p\n", newNode->next); 
} 
+1

確かに簡単な修正があります。「void insert」を取り除いて頭を戻してください。 –

+1

または、ダブルポインタを使用し、参照を使用して値を更新してください。 – Haris

+0

私はあまりにもそれを提案しようとしていた。新しいリンクリストが返されました。次のように使います: 'list = insert(list、number)' – nielsbot

答えて

1

私は簡単に修正が新しいリストの先頭を返すために、あなたの関数を変更することだと思う:

Node * insert(struct Node * list, int value) 
{ 
    ... 
} 

次のように使用してください:それは難しい

myList = insert(myList, someNumber)


あなたが写真なしで望むユースケースを説明する。リストヘッドポインタへのポインタをに渡したいとします。 insert()の内部では、そのポインタポインタが指しているものを修正して(逆参照して)リストの頭を変更することができます。

はこのようにあなたの関数を宣言します。

void insert(struct Node ** ioList, int value) { ... } 
ここ

ioListNodeへのポインタへのポインタであるタイプNode **、です。 (経験則:右から左へのタイプを読んで)

はこのようにそれを呼び出します。

struct Node * myList = /*create list here*/ ; 
insert(&myList, /*some number*/); 

&オペレータは、それへのポインタが引数の作成します。そこで、myListへのポインタを取得しています。 (Nodeへのポインタ)

ここでは、myListを指すポインタがあります。 insert内部

、(myList)に何ioList点を変更するために*ioListに割り当てる:

// make myList point to the new list head: 
*ioList = /*new list head*/ 
+0

私はポインタを返すことで問題を解決できることを知っていますが、この解決法はより洗練されたようです。私はちょうどポインタのハングを取得していたように感じたが、私は少しポインタをポインタの周りに私の頭を取得する必要があると思う... –

+0

あなたのコードでは、insert()あなたのリストポインタ...これが起こるところでは、コードのバグを管理して見つけにくいです。私は個人的に新しいリストヘッドを返す最初のオプションを使用します。 – nielsbot

0

ポインタはメモリ内の位置を指します。あなたの関数は新しいメモリ位置を作成し、それを値渡しのポインタに代入します。私はあなたが既存のリンクされたリストに新しいノードを追加しようとしていると仮定します。

あなたの関数は、残念なことに、リンク先リストに新しいアドレスを割り当てるたびにこの方法では動作しません。

私はスパース配列の使用が好きです。リストの最大サイズを知っていれば、後で再配置する必要のある構造体を格納する連続したメモリ位置よりも使いやすくなります。

void insert(struct node* list[], int *currentIndex, int value) 
{ 
    struct node * newNode; 

    newNode = malloc(sizeof(node)); 
    list[*currentIndex++] = newNode; 

    .... 
} 
+0

私はCS50のプログラミング課題の一部としてリンクリストを探しています。リンクされたリストを使用する理由は、あらかじめリストのサイズを知る必要がないためです。 1つは新しいノードがリストに追加されるときに新しいノードが作成されます。この例のノードは、整数と次のノードへのポインタしか保持していません。 –