【问题标题】:Passing structs of a linked list by reference通过引用传递链表的结构
【发布时间】:2019-09-11 11:57:52
【问题描述】:

我正在完成一个需要为纸牌游戏实现链接列表的最终项目。庄家手和闲家手都应该是链表以及一副牌。

我遇到的问题是,当我尝试创建一个将值(来自套牌列表末尾的卡片)添加到它的函数时。将列表传递给它自己及其尾部不会更新它们的值。我可以使函数返回头指针,但是我将无法记下它的尾巴。

我真的很抱歉,因为这对我来说是新事物,而且我在这门课程之前从未编程过。如果我的函数中的某些逻辑看起来不必要地难以阅读,或者直接没有意义,请原谅我。

我已经无休止地尝试让这项工作发挥作用,但我觉得我做的事情根本上是错误的

typedef struct card_s { 
    char suit[20]; 
    int face; 
    struct card_s *next, *previous; 
} card;

card* createHands(card* head, card *cards) {
    card *tail = NULL, *temp = NULL, *temp1;

    // Go to end of deck
    while (cards->next != NULL) {
        cards = cards->next;
        }

        temp = (card *)malloc(sizeof(card));
        strcpy(temp->suit, cards->suit);
        temp->face = cards->face;
        if (head == NULL) { // If the list for the hand doesn't exist, create head
            head = temp;
        }
        else {
            tail->next = temp;
        }
            tail = temp;
            tail->next = NULL;

        temp1 = cards->previous; 
        free(cards); // to delete the node added from the deck

        cards = temp1;
        cards->next = NULL;
        while (cards->previous != NULL) {
            cards = cards->previous;
        }

    return head;

}

显然,这只会将我给它的任何值添加到以前的值之上。这绝不是一个连接列表。

我将不胜感激!

【问题讨论】:

  • free 旧节点并 malloc 一个新节点没有任何意义 - 只需将 that 节点放入正确的列表中并完成它!
  • 我明白你的意思,我会尽快修复这个功能。
  • N,你应该努力在你的问题中产生一个minimal reproducible example。例如,请注意最后一个 while 循环实际上没有任何效果。
  • 您永远不会为分配的节点设置previous。所有这一切都源于您的函数是如此复杂,以至于每个人都很难弄清楚其中发生了什么。
  • if (head == NULL) - 什么时候 not 在初次进入此函数时为真?我的意思是,当您将非空 head 传递给这个东西时?这个函数到底应该做什么?如果你不能走你的代码和explain it to your rubber duck,你将很难向我们解释它。

标签: c pointers linked-list


【解决方案1】:

您的代码中有几个明显的问题:

  • while (cards->next != NULL) 假设 cards 不为 NULL
  • 如果 head 不为 NULL,则您执行 tail->next = temp;tail 为 NULL
  • 您从 cards 中释放了最后一个单元格而不更新该列表,因此它的最后一个元素现在被释放了

如果我很好理解 createHands 的第二个参数是套牌,以及提取其最后一张牌以将其添加到庄家/玩家列表中并返回它的新头像的目标。 p>

请注意,您需要将牌组设为card ** 才能在提取最后一张牌时将该列表设置为 NULL。也可以对庄家/玩家列表采用相同的方式,但显然您更喜欢返回新的头像而不是将第一个参数设置为 card ** head

假设卡片必须加在头上,一个解决方案可以是:

card * createHands(card * head, card ** deck) {
  if (deck == NULL)
    // no available card
    return head;

  // Go to end of deck
  while ((*deck)->next != NULL) {
    deck = &(*deck)->next;
  }

  card * c = *deck; // the extracted card

  *deck = NULL; // remove it from the deck

  c->previous = NULL;

  if (head != NULL) {
    c->next = head;
    head->previous = c;
  }

  return c;
}

要检查的完整程序:

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

typedef struct card_s { 
    char suit[20]; 
    int face; 
    struct card_s *next, *previous; 
} card;

card * createHands(card * head, card ** deck) {
  if (deck == NULL)
    // no available card
    return NULL;

  // Go to end of deck
  while ((*deck)->next != NULL) {
    deck = &(*deck)->next;
  }

  card * c = *deck; // the extracted card

  *deck = NULL; // remove it from the deck

  c->previous = NULL;

  if (head != NULL) {
    c->next = head;
    head->previous = c;
  }

  return c;
}

// check

card * mk(const char * s, card * n)
{
  card * c = malloc(sizeof(card));

  strcpy(c->suit, s);
  c->next = n;

  if (n != 0)
    n->previous = c;

  return c;
}

void pr(const char * who, card * c)
{
  printf("%s cards :", who);
  while (c != NULL) {
    printf(" %s", c->suit);
    c = c->next;
  }
  putchar('\n');
}

int main()
{
  card * deck = mk("one", mk("two", mk("three", mk("four", mk("five", NULL)))));
  card * dealer = NULL;
  card * player = NULL;

  pr("deck", deck);

  puts("->dealer");
  dealer = createHands(dealer, &deck);
  pr("deck", deck);
  pr("dealer", dealer);

  puts("->player");
  player = createHands(player, &deck);
  pr("deck", deck);
  pr("player", player);

  puts("->dealer");
  dealer = createHands(dealer, &deck);
  pr("deck", deck);
  pr("dealer", dealer);

  puts("->player");
  player = createHands(player, &deck);
  pr("deck", deck);
  pr("player", player);

  puts("->dealer");
  dealer = createHands(dealer, &deck);
  pr("deck", deck);
  pr("dealer", dealer);

  return 0;
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall -g l.c
pi@raspberrypi:/tmp $ ./a.out
deck cards : one two three four five
->dealer
deck cards : one two three four
dealer cards : five
->player
deck cards : one two three
player cards : four
->dealer
deck cards : one two
dealer cards : three five
->player
deck cards : one
player cards : two four
->dealer
deck cards :
dealer cards : one three five

【讨论】:

    【解决方案2】:

    对函数的功能做了很多假设

    typedef struct card_s { 
        char suit[20]; 
        int face; 
        struct card_s *next, *previous; 
    } card;
    

    你想加一张手牌

    card* AddCard(card* hand, card* draw) {
        // check input
        if(draw == NULL ) {return NULL;} 
    
        // create a copy of the card
        card* newCard=malloc(sizeof(card));
        if(newCard == NULL) {return hand;} // check malloc result
        memcpy(newCard, draw, sizeof(card));
        newCard->next=NULL;
        newCard->previous=NULL;
    
        if(hand==NULL) {return newCard;} // if the hand was null just return the card
    
        // find where to append the card
        card* tail=hand; 
        while(tail->next != NULL) {tail = tail->next;}
        // append the card to the end of the hand
        tail->next = newCard;
        newCard->previous = tail;
        return hand;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-06-04
      • 2013-05-12
      • 2011-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-13
      • 2021-06-06
      相关资源
      最近更新 更多