3

プッシュ、ポップなどの基本的なスタック データ構造操作を実装する C コードを書いていました。スタックの Linked List 実装を使用しています。この実装では、スタックに値をプッシュするたびに、新しいノードを作成し、それをリンク リストのヘッド ノードとして設定します。したがって、これにはヘッド ノードの参照の変更が含まれます。

void push(stack **t, int ele)
{
stack *new, *temp;
temp=*t;
new=(stack *)malloc(sizeof(stack));
if(new==NULL)
{
    printf("\n stack overflow");
    return;
}
new=(stack *)malloc(sizeof(stack));
new->val=ele;
new->next=*t;
*t=new;

}

単一のポインタを使用して同様のコードを書くとしたら、次のようになります

void push(stack *t, int ele)
{
stack *new, *temp;
temp=t;
new=(stack *)malloc(sizeof(stack));
if(new==NULL)
{
    printf("\n stack overflow");
    return;
}
new=(stack *)malloc(sizeof(stack));
new->val=ele;
new->next=t;
t=new;

}

関数では、先頭ノード (**t) がすべてのステップで代入の RHS に表示されますが、これは

 *t=new;

基本的に、最初のコードは 'new' を **t のポインター、つまり *t に割り当て、2 番目のコードは 'new' を *t のポインター、つまり t に割り当てます。どちらも、ヘッド ノードへの 1 つのポインターのみを「新規」として割り当てる必要があるように見えますが、最初のコードのみが機能し、2 番目のコードは実際にはヘッド ノードの値を変更しません。

これが起こる理由は何ですか?2 番目のコードが最初のコードと同じように機能しないのはなぜですか?

4

2 に答える 2

3

Cのすべてが値渡しされるためです。そのため、関数の引数に新しい値を割り当てる必要がある場合は、間接的なレベルを追加する必要があります。そうしないと、単にローカル コピーを受け取るだけなので、そのコピーに割り当てられた値は関数内でのみ表示されます。

余談ですが、Cでは の戻り値をキャストしないでくださいmalloc。これは不要であり、コードが乱雑になり、デフォルトの int を許可するコンパイラのエラーを隠す可能性があります。

次のようなものを書く代わりに..別の補足事項:

new_stack = malloc(sizeof(stack));

代わりにこれを使用してください:

new_stack = malloc(sizeof(*new_stack));

これで、型が変わっても問題ありませんnew_stack

于 2013-03-27T19:16:01.273 に答える