5

私が読んだ多くの例では、単純な getListLength() 関数は次のようになります。

int getListLength(struct node *head)
{
    struct node *temp = head;
    int iCount = 0;

    while (temp)
    {
        ++iCount;
        temp = temp->next;
    }

    return iCount;
}

不要だと思われるのは、渡されたパラメーターをコピーするローカル ポインター (この場合は *temp) の宣言です。私の記憶が正しければ、渡されたパラメーターは独自のコピーを取得します。したがって、*head 自体がコピーであるという理由だけで、*head をコピーするローカル ポインターは必要ありませんよね? つまり、*temp ポインターを破棄して、代わりに head をどこでも使用するのが正しいでしょうか?

4

3 に答える 3

4

ポインターが値渡しされるため、ローカル コピーが必要ないことは事実ですが、スタイル上の理由から存在する可能性があります。渡された引数を変更するのは悪い形式だと考える人もいますが (シナリオによっては便利だと思いますが)、おそらくもっと重要なのは、コード内の自己文書化の一部が失われることです。具体的にheadは、リンクされたリストの真の先頭を常に指すとは限りません。短いコードではそれほど混乱することはありませんが、コードが長く複雑になると、不正確な名前の変数があるとさらに混乱する可能性があります。

于 2013-01-05T21:01:50.630 に答える
4

はい、それはコピーですので、はい、それは正しいでしょう。

int getListLength(struct node* head)
{
    int iCount = 0;

    while (head)
    {
        ++iCount;
        head = head->next;
    }
    return iCount;
}

実際に実行して確かめてみませんか?

于 2013-01-05T20:46:21.037 に答える
2

多くの場合、渡されたポインターのローカル コピーを作成する理由は、(関数パラメーターを変更しないことによって) 関数の副作用を減らすためです。

関数が(書き込みではなく)読み取りのみにポインターを使用し、外界との相互作用が他にない場合、関数は GCC で「純粋」と注釈を付けることができ、適切な最適化のために開かれます。

例:

__attribute__((pure)) int getListLength(struct node *head) 
{
    struct node *temp = head;
    int iCount = 0;

    while (temp)
    {
        ++iCount;
        temp = temp->next;
    }

    return iCount;
}

副作用についてよく知らない場合は、ウィキペディアの記事「副作用関数型プログラミング」を読んで、この件に関する詳細情報を入手してください。

于 2013-01-05T21:47:53.877 に答える