2016-08-29 1 views
-2

私は、リストの先頭にノードを追加し、新しいノードを格納する変数 "head"(リストの前の先頭を保持する)を変更する関数を作ろうとしました。リンクされたリストの頭が変わっていないのはなぜですか?

void addToStart(node * n, node * first){ 
    printf("[Before adding] Node: %d, First: %d\n",&(*n),&(*first)); 
    n->next = first; 
    first = n; 
    printf("[After adding] Node: %d, First: %d\n",&(*n),&(*first)); 
} 


int main(){ 
    node * head = createNode(0); 
    printf("This is the location of head: %d\n",&(*head)); 
    node * fred = createNode(2); 
    addToStart(fred,head); 
    traverse(head); //Displays the list starting from the given node 
    return 0; 
} 

これが出力されます。

This is the location of head: 10113040                                     
[Before adding] Node: 10113072, First: 10113040                                   
[After adding] Node: 10113072, First: 10113072                                   
(0)[10113040]->NULL 

は、問題は、私はheadがで指していた内容を変更する機能を期待していることであるが、実際には何も変わっていません。

+0

'first = n'は' addToStart'の関数パラメータ 'first'を変更しますが、' main'の 'head'は変更しません。 'first'は' head'のコピーです。なぜなら、Cは値渡しでコピーだけが変更されるからです。 –

+0

これは 'void f(int n){n = 0;}と同じ理由です。 } 'は、整数をゼロに設定するために使用することはできません。 Cのすべてのものと同様に、まずintの状況を理解してから、他のタイプに一般化してみてください。 –

+0

あなたは 'int'状況については正しいですが、変数自体を保持するのではなく、変数を指すポインタではありませんか?私はポインタ変数を渡すと仮定し、ポインタを変更すると元の変数も効果的に変更されます。 –

答えて

0

addToStartは、node *としてコピーのヘッドポインタを使用するためです。ヘッドを変更するには、C言語で編集すべての機能を

void addToStart(node * n, node ** first){ 
          // ^
    printf("[Before adding] Node: %d, First: %d\n",&(*n),&(**first)); 
    n->next = *first; 
      //^
    *first = n; 
//^
    printf("[After adding] Node: %d, First: %d\n",&(*n),&(**first)); 
} 

を使用する必要があるパラメータの独自のコピーを取得するため、C++や他の言語で同様の参照のようなものは本当にありません。参照を使用する場合は、すばやく汚れたオプション(常に機能するとは限りません)は、それぞれの言葉の前に余分に*を貼り付けることです。ここでは、firstを参照したかったとします。 firstはノードポインタなので、すでにnode *です。それを "参照"(そのまま)として使用するには、*を追加します。したがって、node **となります。同様に、どこに参照されても、**first = ...が追加されます。

Java内部の詳細については、a Java answer that's relatedを参照してください。基本的に、最初の*はJavaインスタンス変数に暗黙的に記述されています。だからJavaのNode n;は、Node *n;のようなCの

のような(並べ替え)であることを願っている - 間違いなく、ページの上部にあるリンクされた重複した質問とその答えをチェックする。別のコードの問題が発生した場合は、別の質問をしてください!

Cウィザードへの注意:はい、盲目的には*を追加することは悪い考えです。しかし、時にはそれは便利です。私はOPのコメントに反応して、OPを一歩前進させるようにしています。

+0

ありがとう、私はあなたがしたことを理解しています。しかし、これは私が私が持っているかもしれない誤解を実現させたと思います。私はポインタがJavaの参照変数に類似していると思った。だから私が引数 'node * first'と 'node * n'を渡したときには、 'first = n'というポインタを変更しないでしょうか? –

+0

@AdnanZaman編集: – cxw

+0

これは私が知らなかったものです。うわー、それは私が過去にしてきた多くの誤りを今よりずっと意味をなさないものにしています。これらのエラーはそれほど神秘的ではありません。私はこれが「価値渡し」の意味であると思います。どうもありがとうございます! –

関連する問題