繁体   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