4

「A Singly Link List」のコードを C で書いていました。このコードでは、リストの最後に要素を挿入したいと考えています。それはうまくコンパイルされました。しかし、実行時に期待される出力が得られません。gccコンパイラとして使用しています。./a.out私が端末でやっているときはいつでも、ハングアップしました。
コードは次のとおりです。

#include<stdio.h>
#include<stdlib.h>
struct list
{
    int node;
    struct list *next; 
};

void insert(struct list *, int);
void print(struct list *);

int main()
{
    struct list *mylist;

    insert(mylist, 10);
    insert(mylist, 20);
    insert(mylist, 30);
    insert(mylist, 40);
    insert(mylist, 50);
    insert(mylist, 60);

    print(mylist);
    return 0;
}

void print(struct list *head)
{
    if(head==NULL)
        return;
    else
    {
            while(head->next!=NULL)
            {
             printf("%d\t",head->node);
             head=head->next;       
        }
    }
}


void insert(struct list *head, int value)
{   
    struct list *new_node;
    new_node = (struct list *)malloc(sizeof(struct list));

//node Creation
    new_node->node=value;
    new_node->next=NULL;

//Adding Node to list
    if(head==NULL)
    {
        head=new_node;  

    }
    else
    {
        while(head->next!=NULL);
        {   
            head=head->next;

        }
        head->next=new_node;

    }

}

これは、リンクリストにinsert()要素を挿入する関数mylistprint()あり、リンクリストのすべての値を出力する関数です。助けてください。私は自分が犯した間違いを見つけることができません。

4

5 に答える 5

5

もう 1 つの変更をお勧めします。つまり、関数のプロトタイプは次のようにする必要があります。

void insert(struct list **, int);
void print(struct list **);

それに応じてボディを変更する必要があります。挿入で新しいメモリ割り当てを行ったので、値渡しではなくアドレス渡しを行う必要があるため、意図したとおりに機能します。

さらに、print 関数では、ループの終了は while((*head)->next != NULL) ではなく while(*head != NULL) にする必要があります。そうしないと、最後のノードがスキップされます。

また、insert 関数を初めて呼び出した後、最初のノードを tmp ポインターに格納し、その tmp ポインターを最後に print 関数に渡す必要があります。あなたのコードでは、ポインタを最後のノードに渡していますが、これは間違っています。だから、それは好きなはずです。

int main()
{
    struct list *mylist=NULL, *tmp = NULL;

    insert(&mylist, 10);

    tmp = mylist;   /* here */

    insert(&mylist, 20);
    insert(&mylist, 30);
    insert(&mylist, 40);
    insert(&mylist, 50);
    insert(&mylist, 60);

    /* At this point mylist is pointing to last node, so pass tmp which stores the first node */
    print(&tmp);    
    return 0;
}
于 2013-08-01T08:07:45.930 に答える
2

いくつかのエラーがあります:

1) コード ライターstruct list *head;. C および C++ では、このような変数は初期化されないことをご存知ですか? NULLグローバルスコープでない限り、それを期待することはできません。ローカル変数は、使用する前に必ず初期化する必要があります。

2)挿入関数はhead値で受け取るため、それを変更すると(リストが空の場合)、ローカルコピーのみが変更され、のhead変数は変更されませんmainheadとして渡すかstruct list **、新しいhead値を main に返す必要があります。list *&C++ では、 (ポインターへの参照)として渡すこともできます。

3)whileループには本体の前に余分なセミコロンがあるため、空のループであり、本体部分はネストされた{...}ブロックであるため、常に(条件に関係なく)正確に1回実行されます。

于 2013-08-01T08:04:34.307 に答える
1

これは良い無限ループです。デバッガを使えば自分で見つけられたかもしれません^^.

while(head->next!=NULL);

メイン関数でリストを初期化する必要もあります。

struct list *mylist = NULL;

また、insert 引数を double ポインターに変更する必要があります (アドレス値をコピーするだけなので、ポインターのみを渡す場合、メインのヘッド リスト値の変更は発生しません)。

void print(struct list *head)
{
  while(head!=NULL)
  {
    printf("%d\t",head->node);
    head=head->next;       
  }
}

void insert(struct list **head, int value)
{   
  struct list *new_node;
  new_node = (struct list *)malloc(sizeof(struct list));

  //node Creation
  new_node->node=value;
  new_node->next=NULL;

  //Get the end of the list
  while((*head)->next!=NULL)
  {   
    (*head)=(*head)->next;
  }

  // Add the node at the end of the list
  (*head)->next=new_node;
}

int main()
{
  struct list *mylist = NULL;

  insert(&mylist, 10);
  insert(&mylist, 20);
  insert(&mylist, 30);
  insert(&mylist, 40);
  insert(&mylist, 50);
  insert(&mylist, 60);

  print(mylist);
  return 0;
}
于 2013-08-01T08:03:46.343 に答える