3

私はこれをいくつかの本/チュートリアルで見ました。

(リンクされたリストの) ヘッド ポインターを関数に渡すときは、ダブル ポインターとして渡す必要があります。

例: // これは、head が最初のノードを指すリンク リストを反転します。

void nReverse(digit **head)
{
    digit *prev=NULL;
    digit *curr=*head;
    digit *next;

    while(curr!=NULL)
    {
        next=curr->next;
        curr->next=prev;
        prev=curr;
        curr=next;
    }
    *head=prev;
    return;
}

これはうまくいきます。

次のような単一のポインターを使用する場合にも機能します。

void nReverse(digit *head)
{
    digit *prev=NULL;
    digit *curr=head;
    digit *next;

    while(curr!=NULL)
    {
        next=curr->next;
        curr->next=prev;
        prev=curr;
        curr=next;
    }
    head=prev;
    return;
}

ヘッドポインタを使ってリストを印刷してみました。どちらの機能も正常に動作します。

何か不足していますか?

ありがとう、

4

5 に答える 5

5

これは C++ ではなく、非常に C に似たコードです。

基本的に、何かが値渡しされると、関数はデータのコピーを操作します。

void foo(int i)
{
    i = 5; // copy is set to 5
}

int x = 7;
foo(x);
// x is still 7

C では、代わりに変数へのポインターを渡し、そのように変更できます。

void foo(int* i)
{
    *i = 5; // whatever i points to is set to 5
}

int x = 7;
foo(&x);
// x is 5

intあなたにとって、それは ではなく ですdigit*。(結果として、ポインターへのポインターになります。)


C++ では、参照が導入されました。参照は、別のオブジェクトへのエイリアスです。したがって、次のようにします。

void foo(int& i) // i is an alias to another value
{
    i = 5; // x is set to 5
}

int x = 7;
foo(x); // pass x as alias, not address of x.
// x is 5

参照は、実際にオブジェクトを参照することを強制し、コードの呼び出しと操作の両方を簡素化するため、一般的に好まれます。

もちろん、C++ では自分でリストを実装するのではなく、std::list.

于 2010-07-22T20:43:09.697 に答える
2

この最後head=prev;の例では、2 番目の例で渡されたポインターの値は変更されません。この関数の目的でその行が必要かどうかは、あなた次第です。しかし、違いがあります。

「正常に動作する」ことをどのようにテストしましたか? リストを反復してノードの値を出力し、それらが実際に逆になっていることを確認できましたか? 最初の関数 (おそらく呼び出されると、何を指すかnReverse(&list); が変更されますが、2 番目の関数はそうではありません (つまり、2 番目の関数では、どのノードがリストの先頭であるかをどのように知ることができますか? 結局、変更されたばかりです...)。list

于 2010-07-22T20:40:48.050 に答える
0

ダブル ポインターを渡す理由 (最初の例) は、リストの先頭を変更するためです。リストを反転しているため、反転を行った後、ヘッドはリストの最後の要素を指す必要があります。

digit* list; 
// initialize list
nReverse(&list); 
// now list is pointing to the last element of the chain (and not the first)

二重ポインタを使用しない場合でも、リストは元の最初の要素を指しますが、反転後の最後の要素であるため、次は NULL を指します。したがって、他のすべての要素を失います。

于 2010-07-22T20:54:21.897 に答える
0

最初の例では、渡したものはまだリストの「先頭」を指しています。

2 番目の例では、リストの末尾を指しています (開始したときは先頭でしたが、移動しました)。

于 2010-07-22T20:43:56.743 に答える
0

二重の間接化の理由はnReverse、呼び出し元のポインターを変更できるためです。これは、リストを反転した後、リストの先頭が別のノードになるためです。

2 番目のバージョンではhead、関数に対してローカルである のコピーを変更しているため、呼び出し元は古いヘッド ノードへの参照をまだ保持しています。

于 2010-07-22T20:46:54.460 に答える