0

「Cを難しい方法で学ぶ」ことを通してCを学び、私自身の演習のいくつかを行います。私は次の問題に遭遇しました。

私が次の構造を持っているとしましょう:

struct Person {
  char name[MAX_INPUT];
  int age;
}

main()で、次の配列を宣言しました。

int main(int argc, char *argv[]) { 
  struct Person personList[MAX_SIZE];
  return 0;
}

ここで、2つの関数が離れているとしましょう(mainはfunction1を呼び出し、function2を呼び出します)。main関数で宣言した配列内の人を次のように保存します。

int function2(struct Person *list) {
  struct Person *prsn = malloc(sizeof(struct Person));
  assert(prsn != NULL); // Why is this line necessary?

  // User input code goes here ... 

  // Now to save the Person created
  strcpy(prsn->name, nameInput);
  ctzn->age = ageInput;
  list = prsn; // list was passed by reference by function1, does main need to pass the array by
               // reference to function1 before?

  // This is where I get lost:
  // I want to increment the array's index, so next time this function is called and a 
  // new person needs to be saved, it is saved in the correct order in the array (next index)
}

したがって、メインの機能に戻って、そこに保存されている最初の3人を次のように印刷したい場合は次のようになります。

...
int i = 0;
for(i = 0; i < 3; i++) {
  printf("%s is %d old", personList[i].name, personList[i].age);
}
...

基本的に、永続性を維持しながら、アプリケーション全体で配列を参照する方法。mainは、必ずしも配列を利用する関数を直接呼び出すとは限らないことに注意してください。誰かがそれをグローバル変数として宣言することを提案しているのではないかと疑っています。それでは、代替手段は何でしょうか?ダブルポインタ?ダブルポインタはどのように機能しますか?

お時間をいただきありがとうございます。

4

2 に答える 2

1

まず第一に、mallocはメモリから新しいスペースを割り当ててそれを返すことを保証しません。要求されたメモリを割り当てることができない場合は、NULL値を返します。そのため、ポインタを確認する必要があります。

関数2を呼び出しているときに、function1の配列の現在のカウントを保持する変数を使用して、次の要素のアドレスを渡すことができます。

function2(&personList [count ++]);

次に、function1からmain関数に現在のカウントを返します。

int size = function1(personList);

于 2012-10-17T04:15:59.833 に答える
1

ここにあなたを助けるためのいくつかの指針があります(しゃれは意図されていません!):

  1. 現状では、この行は構造体の数にstruct Person personList[MAX_SIZE];メモリを割り当てています。これがあなたがしていることであるならば、あなたは実際に使用してより多くのメモリを割り当てる必要はありません。MAX_SIZEPersonmalloc

  2. ただし、実際に人が必要な場合にのみメモリを割り当てることで、メモリを節約できます。この場合、(を使用して作成した)構造体自体ではなく、構造体へのポインターpersonList配列に含める必要があります。Personmalloc

    あれは:struct Person * personList[MAX_SIZE];

    人を作成するとき:

    struct Person * person = (struct Person *) malloc(sizeof(struct Person));

    personList[index] = person;

    そして、あなたが人リストを使うとき:printf("%s", personList[index]->name);

  3. 配列は、特別なインデックスの記録を魔法のように保持することはありません。これは自分で行う必要があります。1つの方法は、配列の長さを、それを必要とする各関数に常に渡すことです。

    void function1(struct Person * personList, int count);

    呼び出し元の関数に戻ったときにcount変数を変更したい場合は、参照によって渡すことができます。

    void function1(struct Person * personList, int * count);

    おそらくより堅牢な方法は、カウントと配列を一緒に別の構造にカプセル化することです。

    struct PersonList { struct Person * list[MAX_SIZE]; int count; }

    このようにして、リストデータを常にコヒーレントに処理する一連の関数を記述できます。新しい人を追加するたびに、常にカウントをインクリメントします。

    int addNewPerson(struct PersonList * personList, char * name, int age);

多くのことがあなたに役立つはずだと思います。より詳細に説明したい場合は、コメントを残してください。

于 2012-10-17T04:30:09.330 に答える