5

したがって、リストをグローバル変数として定義しています。

typedef struct center {

  char center_name[100];

  char hostname[100];

  int port;

  struct center *next_center;

} center;

リストに要素を追加する必要があります。しかし、追加する必要があるこれらの要素はファイル上にあるため、次のようになります。

 int main(int argc, char** argv) {
     center *head = NULL; 
     parse(argv, head);
  }

parse は、ファイルを読み取り、それらの読み取り要素を新しいセンターに追加する関数です (これはすべて機能し、二重チェックされます)。

void parser (char** argv, center *head) {
   //read the elements i need to add
   //creates a newCenter and adds the elements read to the new center
   //this far it works
  addToCenter(newCenter, head); 
}

どこ:

addToCenter(center *newCenter, center *head){
   //adds newCenter to the list
   if (head == null)
      head = newCenter;
   else {
      //find last element
      lastelement.next_center = newCenter; 
   }

}

Main のリストが常に null として返されることを除いて、すべてが機能します。つまり、参照は変更されていません。リストへのポインターを渡しているため、理由がわかりません。

別の解決策は、リストのヘッド変数をグローバル変数として作成することですが、そのような状況を回避することをお勧めします。

前もって感謝します。

4

5 に答える 5

7

リスト ヘッドが値渡しされています。変更された場合に備えて、ヘッドポインターをアドレスで渡す必要があります(変更されます)。

例:

addToCenter(center *newCenter, center *head) // <=== note: passed by value
{
   //adds newCenter to the list
   if (head == null)
      head = newCenter; // <=== note: modified local stack parameter only.
   else {
      //find last element
      lastelement.next_center = newCenter; 
   }
}

次のようにする必要があります。

addToCenter(center *newCenter, center **head) // <=== note: now passed by address
{
   //adds newCenter to the list
   if (*head == null)
      *head = newCenter;  // <=== note: now modifies the source pointer.
   else {
      //find last element
      lastelement.next_center = newCenter; 
   }
}

同様にパースで:

void parser (char** argv, center **head) // <=== again, the head-pointer's *address*
{
   //read the elements i need to add
   //creates a newCenter and adds the elements read to the new center
   //this far it works
  addToCenter(newCenter, head);  // <=== just forward it on.
}

そして最後にメインに戻ります:

int main(int argc, char** argv) 
{
     center *head = NULL; 
     parse(argv, &head);  // <=== note: passing address of the head-pointer. (thus a dbl-pointer).
}
于 2013-01-26T13:58:41.020 に答える
3

次のように渡す必要があります。

void parser (char** argv, center **head) {
   //read the elements i need to add
   //creates a newCenter and adds the elements read to the new center
   //this far it works
  addToCenter(newCenter, &head); 
}

addToCenter(center *newCenter, center **head){
   //adds newCenter to the list
   if (*head == null)
      *head = newCenter;
   else {
      //find last element
      lastelement.next_center = newCenter; 
   }

}

そして主に:

int main(int argc, char** argv) {
     center *head = NULL; 
     parse(argv, &head);
}

C の値はデフォルトで値渡しされるため、これを行う必要があります。リストのアドレスを参照ではなく値で渡しているためです。上記のプログラムのように変数headを参照渡しすると、リストを変更してデータをリストに戻すことができます。それ以外の場合は、値渡しになり、 の値headは決して変更されません (したがって、 が得られますNULL) 。

于 2013-01-26T13:59:27.727 に答える
2

ポインターを関数に渡すと、ポイント先の値を関数の外に代入した結果を確認できます。ただし、ポインター自体は引き続き値渡しされます。

head内で変更するには、ポインタを両方の関数に渡す必要があります。parseraddToCenterhead

void parser(char** argv, centerPtr **headPtr) {
     /* rewrite using *headPtr instead of head */
}
void addToCenter(center *newCenter, center **headPtr) {
     /* rewrite using *headPtr instead of head */
}
int main(int argc, char** argv) {
    ....
    parser(argv, &head);
    ....
}
于 2013-01-26T13:58:43.640 に答える
1

関数では、ポインター自体ではなく、ポインターのローカル コピーを変更します。ポインタへのポインタを取るように関数定義を変更する必要があります。

于 2013-01-26T13:58:36.480 に答える
1

ポインターロジックに関する知識の一部が欠けているようです。ここで何が問題なのかを説明しようとします。

まず、 anyvoid*を asintに書き換えましょう。これは、(一種の) 内部で起こることです。

addToCenter(int newCenter, int head){
   //adds newCenter to the list
   if (head == 0)
       head = newCenter;

さて、問題はそれ自体を示しています。

ソリューション?

addToCenter(center *newCenter, center **head){
   //adds newCenter to the list
   if (*head == null)
       *head = newCenter;
于 2013-01-26T13:59:11.910 に答える