2

cでリンクリスト構造体を作成しました

struct node{
   int value;
   struct node* next;
};

リストの先頭にノードを追加するメソッド:

void addFirst(struct node *list, int value){
    struct node *new_node = (struct node*) malloc (sizeof (struct node));
    new_node->value = value;
    new_node->next = list;
    list = new_node;
   }

リスト(mallocとすべて)を作成し、このメソッドを呼び出すと、メソッド内に新しいノードが追加されますが、メインに戻ると、古いリストは変更されません。DDDデバッガーを使用してすべてをチェックします。これはどのように可能ですか?メソッドのシグネチャを変更できないため、このようにする必要があります。

4

6 に答える 6

6

この方法では、ノードポインタを関数に変更できませんでした。この関数では、ポインタのアドレスではなく、ポインタの内容を変更できます。するには、ポインタのポインタを渡す必要がありますstruct node **list

ここでそれを行う方法の後:

void addFirst(struct node **list, int value){
    struct node *new_node = (struct node*) malloc (sizeof (struct node));
    new_node->value = value;
    new_node->next = *list;
    *list = new_node;
}

またはあなたはこのようにそれを行うことができます

struct node * addFirst(struct node *list, int value){
    struct node *new_node = (struct node*) malloc (sizeof (struct node));
    new_node->value = value;
    new_node->next = list;
    return new_node;
}

そしてあなたのタラでは、この関数の呼び出し後に頭を得ることができます

head = addfirst(head,45);
于 2012-10-01T13:54:43.810 に答える
5

本当にこの方法で行う必要がある場合は、ポインターを再キャストする必要があります。このようなもの:

struct node *my_list = null;
addFirst((struct node *)&my_list, 123);

void addFirst(struct node *list, int value){
    struct node **real_list = (struct node **)list;
    struct node *new_node = (struct node*) malloc (sizeof (struct node));
    new_node->value = value;
    new_node->next = *real_list;
    *real_list = new_node;
}
于 2012-10-01T14:00:55.233 に答える
3

Cでは、関数が引数で受け取った値を変更できるようにする場合は、その値のアドレスを渡す必要があります。したがって、リストポインタの値を変更するには、リストポインタのアドレスを渡す必要があります。addFirst()関数は次のようになります。

void addFirst(struct node **list, int value){
     struct node *new_node = (struct node*) malloc (sizeof (struct node));
     new_node->value = value;
     new_node->next = *list;
     *list = new_node;
}

そして、その関数を呼び出すときは、次のように呼び出します。

addFirst(&list, value);

ここで、関数のシグネチャを保持したい場合は、ヘッドノードの考え方を変更する可能性があります。ヘッドノードの目的が最初の値へのポインターを保持することだけであり、それ自体に値が含まれていないことを示す場合は、次のようにすることができます。

struct node *head;

void addFirst(struct node *list, int value){
     struct node *new_node = (struct node*) malloc (sizeof (struct node));
     new_node->value = value;
     new_node->next = list->next;
     list->next = new_node;
}

addFirst(head, 45);

これで、リストで機能するすべての関数のみが変更されるため、同じように機能します。「head」はリストの実際の最初のノードのみを指し、リスト自体のメンバーではないことを考慮してください。「本当の」頭は、すべての実用的な目的のために、頭->次です。

于 2012-10-01T13:57:01.980 に答える
2

@Vlad Lazarenkoの答えを学び、このようなコードを作成しましたが、正しいですか?

addFirst((struct node**)head,123);

void addFirst(struct node **list,int value)
{
    struct node *new_node=malloc(sizeof(struct node));
    new_node->value=value;
    new_node->next=*list;
    list=&new_node;
}
于 2014-03-06T06:56:00.640 に答える
1
void addFirst(struct node **list, int value){
    struct node *new_node = (struct node*) malloc (sizeof (struct node));
    new_node->value = value;
    new_node->next = *list;
    *list = new_node;
}

これは正しいコードです。問題は、通過するpoineterstruct node *listはスタック変数であるため、変更できないことです。これを変更するとstruct node **list、リストの最初のノードへのポインターが渡されます。これで、リストの新しい最初のノードを指すように変更できます。

于 2012-10-01T13:52:58.453 に答える
1

すべてが良好ですが、void addFirst(struct node *list, int value)関数でlistは値が渡されます。これは、ポインタがコピーされており、addFirst関数内のそのポインタへの新しいアドレスの割り当てがの呼び出し元に表示されないことを意味しますaddFirst。これを解決するには、ポインタをポインタ(struct node **)で渡すか、戻り値にして、呼び出し元が新しい「ヘッド」として使用するように要求する必要があります。

;そして、構造体宣言の後で忘れないでください。

于 2012-10-01T13:54:45.420 に答える