2011-07-27 10 views
3

私は、単独でリンクされたリストについて本当に簡単な質問があります。これは他の質問で答えが見つかりませんでした。単独リンクされたリスト - C

これは私のコードです:今

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

void add(int data); 
void printList(); 

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

struct node * head = NULL; 

main() 
{ 
    char c; 

    while ((c = getchar()) != 'q') 
    { 
     if (c == 'a') 
     { 
      int temp; 

      printf("data: "); 
      scanf("%d", &temp); 

      add(temp); 
     } 

     if (c == 'p') 
      printList(); 
    } 
} 

void add(int data) 
{ 
    struct node * temp = (struct node *) malloc(sizeof(struct node)); 

    if (temp == NULL) 
     fprintf(stderr, "error"); 

    temp->link = head; 
    temp->data = data; 
    head = temp; 
} 

void printList() 
{ 
    struct node * temp = (struct node *) malloc(sizeof(struct node)); 

    if (temp == NULL) 
     fprintf(stderr, "error"); 

    temp = head; 

    while (temp != NULL) 
    { 
     printf("%d", temp->data); 
     temp = temp->link; 
    } 
} 

、私は、新しいリストが作成されている場合は異なる何かをする私のadd関数の内部機能やシナリオを作成する必要があると言われています。言い換えれば、リストが空で、最初の要素が追加されているときは、入力されたリストが正面の別のノードを受け取っているときとは異なる処理が必要です。

# // Adding a Node at the Beginning of the List 
# 
# void addBeg(int num) 
# { 
# struct Node *temp; 
# 
# temp=(struct Node *)malloc(sizeof(struct Node)); 
# temp->Data = num; 
# 
# if (Head == NULL) 
# { 
#  //List is Empty 
#  Head=temp; 
#  Head->Next=NULL; 
# } 
# else 
# { 
#  temp->Next=Head; 
#  Head=temp; 
# } 
# } 

あなたが気づかれるように、リストが空の場合は、ヘッドノードが移入さ:私はそのようなコードのオンラインの例を発見しました。

私のコードは正常に動作しますが、nullヘッドの状況を処理することに関して何かを見落としているかどうかは疑問です。

多くの感謝!

+4

add()関数は機能しますが、mallocが失敗した場合はsegフォールトが発生します。 'temp == NULL'なら' return'する必要があります。 printで新しいノードをmallocする必要はありません。頭にポインタを使うだけで十分です。メモリがリークしています –

+2

printList関数にはバグがあります:新しい一時ノードをmallocし、すぐにmallocのポインタをヘッドポインタで上書きして、割り当てられたノードをリークします。この場合、割り当ては不要です。 –

+0

ああ!あなたが正しいです!ありがとう! – seyelent

答えて

6

add()機能に根本的な問題はありません。 head == NULLが特別な治療を必要としない場合。

他人が気付いたように、が失敗した場合に関数から復帰する必要があるため、エラーチェックは正しくありません。あなたのadd()機能は、tempNULLのとき*tempに割り当てようと試みます。

あなたがこのような特別扱いで示したコードは偽です。そのコードのelse句は、head == NULLと完全にうまく機能します。

+1

興味深い。ありがとう!私は学校で別々にやるように教えられていたのはとても奇妙なことが分かりました。しかたがない! – seyelent

+0

+1 mallocがnullを返すと、コアがダンプされます – Konstantin

+0

申し訳ありませんが、わかりやすく、私のコードは問題ありません。 nullのインスタンスをチェックするのが最善ですが、それ以外の場合、私のプログラムは予期しない不具合を生成するべきではありませんか?もう一度ありがとう! – seyelent

1

ヘッドを使用するたびにポインタがnullであるかどうかをチェックするか、ヘッドノードを別に処理した場合にnullではないと考えることができます。

良いマナーは、常にそれをチェックすべきだと考えていますが、ヌルポインタを参照しないで参照しないと、あなたのコードはとにかく動作します。

0

あなたが考える場合はaddBegかの支店:

if (Head == NULL) 
{ 
    Head=temp; 
    Head->Next=NULL; 
} 
else 
{ 
    Head=temp; 
    temp->Next=Head; 
} 

あなたがtempheadに割り当て、その後nextポインタを設定していることがわかります。 あなたの実装では、他の一方で、次のとおりです。

temp->link = head; 
temp->data = data; 
head = temp; 

、あなたは(どちらの場合にも存在し、head = tempdata部分をスキップした場合、あなたは

ので、それは最初のものと同等であることがわかりやすくなります
temp->link = head; 

と同じである:(ノードを追加するとき)は、常にラインを実行しますので

if (Head == NULL) 
{ 
    Head->Next=NULL; 
} 
else 
{ 
    temp->Next=Head; 
} 
+3

'Head == NULL'のとき、' Head-> Next = NULL'はプログラムを必ずクラッシュさせます。 –

+0

@larsmans:私の悪い!あなたは正しいです、私は私の答えを編集しました、推論はまだ保持しています... – sergio

1

head = temp; 

ノードを追加した後は、ヘッドノードにNULL参照がありません。これは、tempがNULLポインタではないことを上記(temp!= null)で確認するためです。

ノードを検索するときに、(何もしない)フィールドにアクセスする前に、ヘッドノードがヌルでないことを確認することは、本当に良い考えです。おそらく、それは「特別な条件」で意味されていたものであり、ノートは一般的に必要でないこのケースと混同されていました。

+0

まあ... tempが 'NULL'でない限り。 –

+1

この場合、コードは上記の4行を終了していました。コーディング(チェスのような)は、地元の出来事と地元の出来事に影響を与える遠くの出来事に焦点を合わせることを求めています。 –

関連する問題