在 C 中创建和显示链表:程序显示不正确

Posted

技术标签:

【中文标题】在 C 中创建和显示链表:程序显示不正确【英文标题】:creating and displaying a linked list in c: program not displaying correctly 【发布时间】:2021-12-27 19:38:35 【问题描述】:

目前正在开发一个创建扑克游戏的程序。现在我正在尝试打印卡片组。它不打印任何东西,而不是在我运行它时以代码零退出,而是以代码 -104356 或类似的东西退出。我正在使用两个功能,一个是制作卡片,另一个是打印它们,我不确定问题出在哪里。

我的代码:

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

typedef struct card_s 
char suit;
int face;
struct card_s* next;
 card;

card* createCard(int n);
void printCard(card* head);

int main(void) 
card* first = NULL;

first = createCard(52);
printCard(first);

free(first);
return(0);

card * createCard(int n) 
int i = 0;
card* head = NULL;
card* tmp = NULL;
card* p = NULL;

for (i = 0; i < n; i++) 
    tmp = (card*)malloc(sizeof(card));
    tmp->face = rand() % (10 + 1 - 1) + 1; //this is supposed to generate a random number between 1 and 10
    tmp->suit = "CDHS"[rand() % 4]; //this is supposed to generate a random letter C, D, H, or S
    
    tmp->next = NULL;
    
    if (head == NULL) 
        head = tmp;
    
    else 
        p = head;
        while (p != NULL) 
            p = p->next;
        
        
        p->next = tmp;
    

return(head);

void printCard(card * head) 
card* p = head;

while (p->next != NULL) 
    printf("%d%s\n", p->face, p->suit);
    p = p->next;

return;

【问题讨论】:

***.com/editing-help 【参考方案1】:

在这段代码中sn-p

else 
    p = head;
    while (p != NULL) 
        p = p->next;
    
    
    p->next = tmp;

在while循环之后,指针p等于NULL。所以下一条语句

    p->next = tmp;

调用未定义的行为。

你至少需要像这样重写循环

    while (p->next != NULL) 
        p = p->next;
    

但无论如何,这种方法是低效的。最好写

if (head == NULL) 
    head = tmp;
    p = head; 

else 
    p->next = tmp;
    p = p->next;

同样在函数printCard中,由于while循环中的条件,列表的最后一个元素没有输出

while (p->next != NULL) 

您也不能像您正在做的那样将转换说明符 %schar 类型的对象一起使用

printf("%d%s\n", p->face, p->suit);

函数可以写成这样

void printCard( const card *head ) 

    for ( ; head != NULL; head = head->next ) 
    
        printf("%d%cn", head->face, head->suit);
    

【讨论】:

【参考方案2】:

其他人已经指出了您实现链表的潜在问题,所以我将提出一些不同的观点。

您可能希望将您的一副纸牌存储在一个链表中——我不知道你的实现,所以这是否是一个好主意,我不能说,但它肯定是有道理的——但这并不意味着您必须单独分配每张卡或一张一张地初始化它们。您可以将一副纸牌创建为一个数组,并仍然用指针将它们链接起来。

如果您这样做,您可以将它们作为一个整体进行分配和释放,并且当您希望添加/附加到空列表时,您可以避免烦人的特殊情况。您可以一次拥有所有卡片,然后将它们串起来。

这种方法也可能更容易洗牌。使用数组,您可以轻松创建随机排列,然后根据该排列将卡片链接起来。排列一个链表可能有点困难。

正如我所说,我不了解应用程序,所以我不知道这个建议是好是坏,但我在下面放了一些示例代码。

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

#define DECK_SIZE 52

struct card

    char suit;
    char const *face;
    struct card *next;
;

struct card *alloc_deck(void)

    static char const *suite = "CDHS";
    static char const *face[] = 
        "A", "2", "3", "4", "5", "6",
        "7", "8", "9", "10", "J", "Q", "K",
        NULL;
    struct card *deck = malloc(DECK_SIZE * sizeof *deck);

    struct card *card = deck;
    for (char const *s = suite; *s; s++)
    
        for (char const **f = face; *f; f++)
        
            *card = (struct card)
                .suit = *s,
                .face = *f,
                .next = card + 1 // point to next card
            ;
            card++;
        
    

    // last card should point to zero
    (card - 1)->next = NULL;

    return deck;


void print_card_list(struct card *deck)

    for (struct card *card = deck; card; card = card->next)
    
        printf("%s%c\n", card->face, card->suit);
    


void print_deck_array(struct card *deck)

    for (int i = 0; i < DECK_SIZE; i++)
    
        printf("%s%c\n", deck[i].face, deck[i].suit);
    


struct card *shuffle(struct card *deck)

    static int perm_init;
    static int perm[DECK_SIZE];
    if (!perm_init)
    
        perm_init = 1;
        for (int i = 0; i < DECK_SIZE; i++)
        
            perm[i] = i;
        
    

    // permute indices
    for (int i = DECK_SIZE - 1; i >= 0; --i)
    
        int j = rand() % (i + 1);
        int temp = perm[i];
        perm[i] = perm[j];
        perm[j] = temp;
    

    // chain up the cards
    for (int i = 0; i < DECK_SIZE - 1; i++)
    
        deck[perm[i]].next = &deck[perm[i + 1]];
    
    deck[perm[DECK_SIZE - 1]].next = NULL; // terminate chain

    return &deck[perm[0]]; // return first in chain


int main(void)

    struct card *deck = alloc_deck();

    printf("Allocated list:\n");
    print_card_list(deck);
    printf("\n");

    printf("Allocated array:\n");
    print_deck_array(deck);
    printf("\n");

    struct card *card = shuffle(deck);
    printf("Shuffled deck:\n");
    print_card_list(card);
    printf("\n");

    card = shuffle(deck);
    printf("Second shuffled deck:\n");
    print_card_list(card);
    printf("\n");

    free(deck); // free deck as a whole

    return 0;

【讨论】:

以上是关于在 C 中创建和显示链表:程序显示不正确的主要内容,如果未能解决你的问题,请参考以下文章

用c语言创建链表

这是我写的C语言创建动态链表程序,但是貌似不能输入啊,输入好几组数据之后,就不显示结果

c语言程序链表问题

如何在 BackboneJS 应用程序中创建和打开警报对话框

如何在 C++ 或 C 中创建和编写索引 png 图像

如何在 JavaFX 2.0 中创建和显示通用对话框(错误、警告、确认)?