2016-04-24 4 views
1

実行時に追加できるプレイヤーのダイナミックな配列を作成しようとしていますが、x座標で3人のプレイヤーを作成した場合は、4,7と15の値を出力してください。 33、20762704.C - 構造体の動的配列を作成し、構造体メンバが間違った値を出力していますか?

私はCとポインタを使い慣れていないし、どこが間違っているのか分からない。

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

// contains data of a player 
struct player { 
    int posX; 
    int posY; 
    int gold; 
}; 

// struct for creating a list of players of dynamic size 
struct playerList { 
    struct player p;  
    struct playerList *next; 
}; 


// add a new player to the list with given coords 
struct playerList *make(int x, int y) { 
    struct playerList *new_player; 
    new_player = (struct playerList *)malloc(sizeof(struct playerList)); 
    new_player->p.posX = x; 
    new_player->p.posY = y; 
    new_player->p.gold = 0; 
    new_player->next = NULL; 
    return new_player; 
} 

// add a player to the list 
void addPlayer(struct playerList *list, int x, int y) { 
    if(list->next) { 
     addPlayer(list->next,x,y); 
    } 
    else { 
     list->next = make(x,y); 
}} 


int main() { 
    struct playerList *players = (struct playerList *)malloc(sizeof(struct playerList)); 

    addPlayer(players, 4,3); 
    addPlayer(players, 7,7); 
    addPlayer(players,15,1); 

    printf("%d\n",players[0].p.posX); 
    printf("%d\n",players[1].p.posX); 
    printf("%d\n",players[2].p.posX); 

    return 0; 

} 
+0

リストの次の可変ポインタを割り当て後にnullに設定するか、calloc関数でメモリを割り当てる必要があります。さらに、あなたは配列ではなく、あなたが配列として動作するprintf関数でリストを持っています! –

+0

@ G.Emadiあなたは私のために拡大できますか?どこをnullに設定すべきですか?リストの各要素をどのように参照して印刷するのですか? – jp963

+3

最初のノードを正しく作成することはありません。 'addPlayer'関数はリストにすでに少なくとも1人のプレーヤーがあるときにプレーヤーを追加するためにしか機能しません –

答えて

1

は、あなたがへのポインタへのポインタplayerListaddPersonに合格しなければなりません。そうでない場合は、タイプ*playerListを返し、呼び出し元関数の変数listに戻り値を代入する必要があります。 playerList **パラメータを関数に渡すのと同じように、成功/失敗を示すポインタと便宜上のポインタを返します。例えば:

/* add a player to the list */ 
playerList addPlayer (struct playerList **list, int x, int y) { 

    struct playerList *node = make (x, y); 
    if (!node) { /* validate new player created */ 
     fprintf (stderr, "error: make player failed for (%d,%d).\n", x, y); 
     return NULL; 
    } 

    if (!*list) /* if first node, set list address to node & return */ 
     return *list = node; 

    struct playerList *iter = *list; /* list pointer to iterate to end */ 

    /* insert all other nodes at end */ 
    for (; iter->next; iter = iter->next) {} 

    iter->next = node; /* add new player at end, return original *list */ 

    return *list; 
} 

はその後main

addPlayer(&players, 4,3); 
... 

に(注:addPlayerはもはや再帰的ではありませんあなたのリストのサイズが大きくなるにつれて、再帰呼び出しのために必要な追加のリソースは、さらに、重要になることができます。新しいプレイヤーを追加するためにリストの最後に手順的な反復がまっすぐ進むので、再帰呼び出しの必要はありません。)

変更を見て、ご不明な点がありましたらお知らせください。 (注:さらなるエラーのためにあなたのコードの残りの部分をチェックしていません)

1

リストには、いくつかのデータを保存するノードがあり、次のノードも指しています。あなたのリストの頭を維持するためにリスト構造を定義することができます。リストやゴミ処理の長さなどの必要な情報を残しておくことができます。

長さを0に設定し、 listをNULLに設定すると、これらの手順はリストの空の状態を示します。

リストに追加する場合は、最後に追加するか、その先頭に追加します。プログラムでは、最後に2番目の挿入ポリシーを選択します。したがって、追加するには、リスト(すべてのノード)をトラバースして最後のノードを見つけ、そのノードの後に​​新しいノードを追加する必要があります。リストが空のときに新しいノードを追加することに注意してください。この場合、リストの先頭を更新する必要があります。 印刷する場合、同様の方法があります。リストの最後にあるヌルポインタに達するまで、リストを走査してノード情報を表示する必要があります。

割り当てが完了したら、割り当てが成功したことを確認してください。ポインタがnullでなければ、成功したことになります。

単純なループを使って新しいノードを追加することができる場合、再帰関数を使用する理由は何ですか?この場合は、ループを使用する方がよいでしょう。

リストの番号が実行時に指定された場合など、一般的に使用されるダイナミックアロケーションメモリです。使用する必要がない場合は、メモリ割り当てが少なくて済みます。たとえば、メインでは、リスト変数を静的変数として定義し、そのアドレスを関数に送ることができます。

私はプログラムをテストし、その出力は大丈夫でした。最初のノードアドレスは、リストのアドレスとなりますので、リストへの最初のプレーヤーを追加するために

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

// contains data of a player 
struct player { 
    int posX; 
    int posY; 
    int gold; 
}; 

// struct for creating a list of players of dynamic size 
struct playerNode { 
    struct player p; 
    struct playerNode *next; 
}; 

struct playerList { 

    struct playerNode *head; 
    int len; 
    // Add other required variables here 
}; 

// add a new player to the list with given coords 
struct playerNode *make(int x, int y) { 
    struct playerNode *new_player; 
    // you need to check memory allocation success 
    new_player = malloc(sizeof(struct playerNode)); 
    new_player->p.posX = x; 
    new_player->p.posY = y; 
    new_player->p.gold = 0; 
    new_player->next = NULL; 
    return new_player; 
    } 
// add a player to the list 
void addPlayer(struct playerList *list, int x, int y) { 
    struct playerNode *player = list->head; 
    if(!player) 
     // you need to check memory allocation success 
     list->head = make(x, y); 
    else 
    { 
     while (player->next) { 
       player = player->next; 
     } 
     // you need to check memory allocation success 
     player->next = make(x, y); 
    } 
    list->len++; 
} 

void showPlayers(struct playerList *list) { 
    struct playerNode *player = list->head; 
    while (player) { 
     printf("%d\n", player->p.posX); 
     printf("%d\n", player->p.posY); 
     printf("%d\n", player->p.gold); 
     printf("--------------------\n"); 
     player = player->next; 
    } 
} 

int main() { 
    struct playerList players; 
    players.len = 0; 
    players.head = NULL; 

    addPlayer(&players, 4, 3); 
    addPlayer(&players, 7, 7); 
    addPlayer(&players, 15, 1); 

    showPlayers(&players); 
    return 0; 

} 
+0

...またそれもコメントします。あなたが追加/削除したもの、さらに重要な理由を確認するのは難しいです。 – Matthieu

関連する問題