0

私はこれら 2 つの構造を使用しています。1 つ目は従業員情報を保持し、2 つ目はリスト情報を保持します。

typedef struct ListNodeTag{
  int idNumber;
  struct ListNodeTag *next;
} Employee;

typedef Employee Item;

typedef struct {
  int size;
  Item *head;
} List;

Peek という関数を使用して、位置、リストの先頭、および Employee 以外の要素へのポインターを送信します。

void Peek (int position, List *L, Item *X) {

  int i;
  Item *currentPtr;

  currentPtr = L->head;

  for(i = 0; i < position; i++){
    if(currentPtr->next == NULL){
      X = currentPtr;
      break;
    }
    currentPtr = currentPtr->next;
  }

  X = currentPtr;

}

このループで main から関数 Peek を呼び出します。

  for(i=0;i<Length(&L);i++){
    Peek(i,&L,&S);
    printf("    %d%\n",idNumber);
  }

その目的は、リストの各メンバーを従業員 ID と共に新しい行に出力することです。ただし、リストの最初のメンバーは、2 番目のメンバーが呼び出されると、その行でセグ フォールトが発生します。currentPtr = currentPtr->next;

リスト内のデータは、次の挿入関数から取り込まれます。

void Insert (Item X, int position, List *L) {
  int i;
  Item *currentPtr,*previousPtr;
  Item *temp = malloc(sizeof(Item));

  temp->idNumber = X.idNumber;
  temp->next = NULL;

  previousPtr = NULL;

  if(L->head == NULL){
     L->head = temp;
  }

  else{
    currentPtr = L->head;
    for(i=0;i<=position && currentPtr!=NULL;i++){
      previousPtr = currentPtr;
      currentPtr = currentPtr->next;
    }
    temp->next = currentPtr;
    previousPtr->next = temp;
  }
  L->size +=1;
 }

印刷すると、セグメンテーション違反なしで結果を取得できますが、リストが長くても同じエントリが繰り返されます。EG: 長さ 3 の場合、次のようになります。

10925
10925
10925
4

1 に答える 1

0

このコードには少なくとも 2 つの問題があります。


最初の問題は、Peek関数にあります。最後の行を見てください。

X = currentPtr;

C は値による呼び出し言語であることを思い出してください。つまり、この行はPeekのローカル値のみを変更し、戻るXときに単に破棄されます。それを見たことがない。Peekmain

Peek次のように変更する必要があります

void Peek (int position, List *L, Item **X) {

そして、最後の行を次のPeekように変更する必要があります

*X = currentPtr;

Xしたがって、 asで渡される値mainをに変更する必要がありますPeekS関数内でどのように宣言したかは述べていませんがmain、現在は次の形式になっていると思います。

Item *S;

次に、それをに変更する必要があります

Item *S[1];

呼び出しはそのPeekままにしておくことができます

Peek(i,&L,&S);

これらの変更の後、長さ 1 のポインターmainの配列を宣言し、のアドレスをto に渡します。thenの最後の行は、 の値が指すアドレスに格納し、配列の最初のポインタを上書きします。SItemSPeekPeekcurrentPtrXItemS


2 番目の問題はforループにあります。

for(i=0;i<Length(&L);i++){
  Peek(i,&L,&S);
  printf("    %d%\n",idNumber);
}

printfがループの反復ごとに異なるものを出力することを期待するのはなぜですか? idNumberループ内でまったく変更されていません! の(修正された)バージョンではPeek、変更されるのは配列の最初の要素だけなSので、次のようなものが必要ですprintf("%d\n", S[0]->idNumber);


X = currentPtr;のループからも削除する必要がありますPeek

if(currentPtr->next == NULL){
  X = currentPtr;
  break;
}

冗長なので; まったく同じ行 ( unmodified 内) がステートメントPeekの直後に実行されます。break

于 2013-09-26T02:16:03.857 に答える