2016-04-24 69 views
1

我想創建一個動態數組,我可以在運行時添加 - 但是如果我用x-coords創建3個玩家:4,7和15,然後嘗試打印這些值,輸出爲:0, 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

你應該在分配或分配帶有calloc函數的內存後,將列表下一個變量指針設置爲null。另外,你的列表不是數組,在printf函數中你的行爲是一個數組! –

+0

@ G.Emadi請你能爲我擴展,應該在哪裏設置爲空?我如何參考列表中的每個元素然後打印? – jp963

+3

你永遠不會正確創建第一個節點。只有在列表中已經有至少一個播放器的時候,'addPlayer'功能纔可用於添加播放器 –

回答

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

在列表中,你有你要保存它的一些數據的節點,並指向下一個節點了。所以,你可以定義列表結構來維護您的列表或頭,列表或垃圾處理可能是一些其他所需信息,例如長度...

有關初始化你應該設置長度和零和頭指針列表爲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