1
#include<stdio.h>
#include<stdlib.h>

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

void insert( struct node *q,int num)
{
    struct node *temp;

    if( q == NULL)
    {
        q = (struct node*)malloc(sizeof(struct node));
        q->data = num;
        q->next = NULL;
    }
    else
    {
        temp = q;
        while( temp != NULL)
        {
            temp = temp->next;
        }
        temp = (struct node*)malloc(sizeof(struct node));
        temp->data = num;
        temp->next = NULL;
    }
}

void display(struct node *q)
{
    struct node *temp;
    temp = q;
    while(temp != NULL)
    {
        printf("%d",temp->data);
        temp = temp->next;
    }
}



int main()
{
    struct node *a;
    a = NULL;
    insert( a,13);
    insert( a,13);
    display(a);
    return 0;
}

insert関数には、qNULL に初期化された構造体ノードへのポインターがあります。

ここで、q が NULL であるかどうかにかかわらず、最初に表示されます。null の場合、ヒープ メモリ、データ、および次のポインターを割り当てています。このようにして、q は最初のデータを逆参照するポインターになります。q が NULL でない場合、q が指す構造体ノードを指す一時ポインターを取得するため、temp が NULL になるまで、temp は temp->next に移動し、ヒープ メモリを割り当て、データと次のポインターを配置しますヌル。

しかし、私の表示機能では何も表示されません。これと、リンクされたリストでスタックとヒープメモリがどのように使用されているかを修正してください。

4

8 に答える 8

3

Cでは、ポインター引数を含め、引数は値渡しであることを思い出してください。

の場合q == NULL、メモリを割り当て、そのメモリを に割り当てますqが、これは関数の外部では変更されません。関数qの のコピーのみが変更されます。q

引数がq 指すものを変更し、それらの変更を関数の外に反映させるには、ポインターにポインターを渡す必要があります。次に例を示します。

void insert(struct node **q, int num)

qの使用方法を変更します。

if (*q == NULL)
    *q = (struct node *) malloc(sizeof(struct node));

さらに、else の場合は、までループしてからtemp->next == NULL、新しいノードを次のように追加する必要があります。

temp->next = (struct node*) malloc(sizeof(struct node));
于 2012-06-22T17:22:17.413 に答える
1

変化する

insert( struct node *q,int num)insert( struct node **q,int num)

および内部main()で、変更

insert( a,13)insert( &a,13)

仮引数ではなく実際の引数を変更する必要があるため、値渡しではなく アドレス渡し使用してください。パス a のアドレスに変更が反映されます。
insert()qa

また、
もう 1 つの問題は、elseブロック内で次 のようにinsert()
変更while( temp != NULL)されます。while( temp->next != NULL)

于 2012-06-22T17:21:17.017 に答える
1

insert()で新しいメモリを割り当てるため、関数でポインターへのポインターを使用する必要がありますmalloc()が、ポインターは引き続きNULLを指します。したがって、ポインター自体を変更するには、パラメーターを使用する場合はポインターへのポインターを使用する必要があります。IMHO、ポインターを返すと、はるかに良くなります。

于 2012-06-22T17:23:10.673 に答える
1

挿入で割り当てられたポインターを返す必要があります。

main では、a は NULL へのポインターです。最初の挿入後、q には a ではなくポインターがあるため、a は NULL へのポインターのままです。

a の値は、構造体ノードを見つけることができるアドレスです。q は a の値のコピーなので、NULL です。malloc() すると、構造体ノードのアドレスである q に値が代入されます、a! は変更されません。

また:

/* a には値があり、q を malloc しません */
主要() {
   構造体ノード a = {0};

   挿入 (&a, 13);
}

また

/* q の値 (構造体ノードのアドレス) を返し、それを a に割り当てます */
struct node *insert(struct node *q, int num) {
   何とか何とか

   qを返します。
}

主要() {
   構造体ノード *a = NULL;

   =挿入(a、13);
}

また

/* リダイレクトが 2 回あるため、これを説明するのは難しいと思います */
void insert( struct node **q, int num ) {

   if ( *q == NULL ) {
   *q = malloc() など
   }
}

主要() {
   構造体ノード *a = NULL;

   挿入 (&a, 13);
}

でも挿入の後半でも似たようなミスをしますよね。メモリを割り当てて next に割り当てる必要があります。その逆ではありません。

于 2012-06-22T17:29:51.253 に答える
0

このコードを自分のものに置き換えます。

    while( temp != NULL)
    {
        temp = temp->next;
    }
    temp = (struct node*)malloc(sizeof(struct node));
    temp->data = num;
    temp->next = NULL;

    while( temp->next != NULL)
    {
        temp = temp->next;
    }
    temp->next = (struct node*)malloc(sizeof(struct node));
    temp->next->data = num;
    temp->next->next = NULL;
于 2012-06-22T17:24:18.257 に答える
0

問題は、リストの最後を繰り返し処理することです。したがって、temp が null になると、終わりを見つけたと言うことができます。そして、新しいノードを作成します。ただし、前のノードを新しいノードに向けることは決してありません。

私はこれを変更します:

while( temp != NULL)

これに:

while( temp->next != NULL)

そのため、最後に到達してもリストへの参照が残っています。それに応じて残りのロジックを変更する必要がありますが、少なくともそれは可能です。

他の人が言っているように、あなたの関数は最初のノードでも機能しません。空のリストを初期化するための別の関数を用意することを検討します。しかし、それは主にスタイルの選択です。

于 2012-06-22T17:23:00.937 に答える
0

これがあなたのプログラムの修正版です。問題は、ポインターが値によって関数にコピーされるため、関数が終了すると、この場合に渡されたポインターはa何にも割り当てられないことです。あなたがした唯一のことは、メモリをリークしたfreeことです。

解決策は、ポインターを参照渡しすることであり、C ではポインターツーポインターで行われます。

#include<stdio.h>
#include<stdlib.h>

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

void insert( struct node **q,int num)
{
    struct node *temp;

    if( *q == NULL)
    {
        *q = (struct node*)malloc(sizeof(struct node));
        (*q)->data = num;
        (*q)->next = NULL;
    }
    else
    {
        temp = *q;
        while( temp != NULL)
        {
            temp = temp->next;
        }
        temp = (struct node*)malloc(sizeof(struct node));
        temp->data = num;
        temp->next = NULL;
    }
}

void display( struct node *q)
{
    struct node *temp;
    temp = q;
    while(temp != NULL)
    {

        printf("%d",temp->data);
        temp = temp->next;
    }
}



int main()
{
    struct node *a;
    a = NULL;
    insert( &a,13);
    insert( &a,13);
    display(a);
    free(a->next); //de-alloc memory
    free(a);
    return 0;
}
于 2012-06-22T17:26:07.647 に答える
0

この問題は 2 つの方法で解決できます。

  1. 関数で q のアドレスを渡します。
  2. 戻り値の型を void から node に変更します。新しいノードを挿入するたびにルート ノードを返します (この方法は簡単ですが、お勧めできません)。
于 2012-06-24T07:06:58.927 に答える