[英]C - Creating a dynamic array of structs, struct members printing wrong values?
我正在嘗試創建一個可以在運行時添加的動態播放器數組-但是,如果我創建3個具有x坐標的播放器:4,7和15,則嘗試打印這些值,輸出為:0、33, 20762704。
我是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;
}
在列表中,您將有一個節點要在其中保存一些數據,並且它也指向下一個節點。 因此,您可以定義列表結構以維護列表的開頭,並可能定義其他一些必需的信息,例如列表的長度或垃圾處理或...
對於初始化,應將長度設置為零,並將列表的頭指針設置為NULL,這些步驟將顯示列表的空白狀態。
當您想添加到列表中時,可以在列表的末尾或頂部添加。 在程序中,最后選擇第二個插入策略。 因此,要添加,您應該遍歷列表(所有節點),找到最后一個節點,並在該節點之后添加新節點。 您應該知道在列表為空時添加新節點,在這種情況下,您應該更新列表的開頭。 對於打印,有一種類似的方法,您應該遍歷列表並打印其節點信息,直到到達列表末尾的空指針為止。
進行任何分配后,您應檢查分配是否成功,如果指針不為null,則表明分配成功。
還有一點,當您可以使用簡單的循環處理添加新節點時,為什么要使用遞歸函數? 在這種情況下,最好使用循環。
最后一點,例如,在運行時指定列表編號時通常使用的動態分配存儲器。 這是一個好主意,如果不必使用,減少內存分配。 例如,在主目錄中,您可以將list變量定義為靜態變量,然后將其地址發送給函數。
我測試了該程序,其輸出正常。
#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;
}
為了將第一個播放器添加到列表中,您必須將指針指向播放器列表傳遞給addPerson
因為第一個節點地址將成為列表地址。 否則,您必須返回*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
不再是遞歸的。隨着列表大小的增加,遞歸調用所需的其他資源addPlayer
重要,此外,由於列表末尾的過程迭代不需要添加新的遞歸調用,因此無需遞歸調用玩家直截了當。)
查看更改,讓我知道是否還有其他問題。 ( 注意:我尚未檢查其余代碼是否有其他錯誤)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.