簡體   English   中英

C-創建一個動態的結構數組,結構成員打印錯誤的值?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM