c - 将指针改组到指向结构的指针
问题描述
我的代码中有 2 个结构;card(value, suit)
和deck(**cards, n)
,我正在尝试洗牌里面的牌。
在shuffle()
函数的 for 循环内部。
第一张卡片之后的第 i 张卡片保存在temp_card
。
随机选择一张卡片并将其分配给第 i 张卡片。
temp_card
分配给随机卡。
问题是程序在这一行停止执行可能是由于分段错误。
**(d->cards + i) = **(d->cards + random_number);
我尝试使用 gdb 进行调试,但不是很具体。这是代码。我还添加了一些卡片和卡片组以main()
对其进行测试,但我对 C 语言还很陌生,所以我也可能会搞砸这些指针的内存位置。
我的改组方法是否正确,或者我应该改变它,为什么程序停在该行,是因为我提供的指针无效吗?
#include <stdio.h>
#include <stdlib.h>
#define VALUE_ACE 14
#define VALUE_KING 13
#define VALUE_QUEEN 12
#define VALUE_JACK 11
typedef enum {
SPADES,
HEARTS,
DIAMONDS,
CLUBS,
NUM_SUITS
} suit_t;
struct card_tag {
unsigned value;
suit_t suit;
};
typedef struct card_tag card_t;
struct deck_tag {
card_t ** cards;
size_t n_cards;
};
typedef struct deck_tag deck_t;
void shuffle(deck_t * d){
card_t temp_card;
int n = d->n_cards;
int random_number;
for (int i = 0; i < n; i++){
temp_card = **(d->cards + i);
random_number = rand() % n;
**(d->cards + i) = **(d->cards + random_number);
**(d->cards + random_number) = temp_card;
}
}
int main(){
deck_t deck;
card_t card1;
card1.suit = 1;
card1.value = 1;
card_t *c_ptr = &card1;
card_t **c_pptr = &c_ptr;
card_t card2;
card2.suit = 2;
card2.value = 2;
card_t *c_ptr2 = &card2;
card_t **c_pptr2 = &c_ptr2;
card_t card3;
card3.suit = 0;
card3.value = 5;
card_t *c_ptr3 = &card3;
card_t **c_pptr3 = &c_ptr3;
card_t card4;
card4.suit = 2;
card4.value = 2;
card_t *c_ptr4 = &card4;
card_t **c_pptr4 = &c_ptr4;
deck.cards = c_pptr;
deck.n_cards = 4;
deck_t *d_ptr = &deck;
shuffle(d_ptr);
}
解决方案
正如评论中已经指出的那样(来自 Barmar & Weather Vane),您的代码不会将 4 张牌插入牌组。只插入第一张牌,其余三张牌与牌组无关。
您需要做的是使用动态分配,以便您可以分配一组卡片。数组的大小必须与一副牌的数量相匹配。
但首先……在套牌中使用双指针似乎很奇怪。因此,首先将其更改为“单个”指针 - 例如:
struct deck_tag {
card_t * cards; // Only one *
size_t n_cards;
};
然后在main
做类似的事情:
int main(){
deck_t deck;
deck.n_cards = 4;
deck.cards = malloc(deck.n_cards * sizeof *deck.cards);
if (!deck.cards) exit(1);
// Now you have 4 cards in the deck and you can
// insert card values directly into the deck.
// There is no need for variables like card1, card2, card3 ...
deck.cards[0].suit = 1;
deck.cards[0].value = 1;
deck.cards[1].suit = 2;
deck.cards[1].value = 2;
... and so on (or better... use loops)
shuffle(d_ptr);
free(deck.cards);
return 0;
}
此外,您还需要更新 shuffle 代码以使用“单个”指针。
推荐阅读
- npm - 在已发布的 NPM 包中使用 styled-jsx 会给出警告:收到非布尔属性 `jsx` 的`true`
- java - Spring boot h2自动配置不起作用
- visual-studio - Visual Studio 不会打开 Safari 进行调试
- javascript - 如何使用 Windows 脚本设置手刹默认预设
- php - 检查 SQL Server 2017 中是否存在 $tablename,如果不存在则创建 TABLE $tablename
- javascript - 根据时间插值变化的值 (glsl)
- unity3d - 我可以为 Unity 网格设置两组顶点颜色吗?
- flutter - 如何在 PageView 中的小部件之间共享数据?
- swift - SwiftUI:删除行时使用 Array/Index 的 ForEach 崩溃
- kubernetes - Kubernetes集群中的DNS解决问题