C 将结构指针指定给双指针结构
问题是:创建一个双指针结构来对卡片进行排序,而不改变每张卡片的内存位置 这些卡用于程序的其他部分 图表:C 将结构指针指定给双指针结构,c,C,问题是:创建一个双指针结构来对卡片进行排序,而不改变每张卡片的内存位置 这些卡用于程序的其他部分 图表: *deck .**card .n_cards +------+ +--------+----+ | x---|------>| x | 3 | +------+ +--------+----+ | +-----+
*deck .**card .n_cards
+------+ +--------+----+
| x---|------>| x | 3 |
+------+ +--------+----+
| +-----+
+------------->| x |
+-----+
.value .suit |
+----+---+ |
| | |<------+
+----+---+
| | |
+----+---+
| | |
+----+---+
代码编译时没有错误,但排序会更改卡的内存地址
我将**卡链接到结构卡的方法是否正确
我正在使用qsort对卡片进行排序
qsort(hand2->cards, hand2->n_cards, sizeof(card_t), card_ptr_comp);
如果您的目标是对
hand2->cards
(类型为card\u t**
)进行排序,则需要将sizeof(card\u t*)
传递到qsort
,并确保比较函数接受card\u t**
作为输入
即
及
(更新)
在调用add\u card\u to
三次后,此图可能会澄清您分配的内容。您将有deck->cards
指向内存中包含三个指针的块,每个指针将指向单独分配的卡
qsort
调用当前正在对指针数组重新排序,即交换deck->cards
所指向数组中指针的顺序。它也是偶然工作的,因为在64位机器上,sizeof(card\u t)
等于sizeof(card\u t*)
card_t**
*deck .cards .n_cards
+------+ +--------+----+
| x---|------>| x | 3 |
+------+ +--------+----+ YOU ARE REORDERING THIS:
| card_t* card_t* card_t*
| +-----+-----+-----+
+------------->| x | y | z |
+-----+-----+-----+
.value .suit | | |
+----+---+ | | |
| | |<------+ | |
+----+---+ | |
| |
.value .suit | |
+----+---+ | |
| | |<------------+ |
+----+---+ |
|
.value .suit |
+----+---+ |
| | |<------------------+
+----+---+
通常的方法是
typedef结构foo_标记{/*…*/}foo_t
(免责声明:是,…\t
可能与POSIX中的标识符冲突。)@Swardfish:单独的结构定义和类型定义没有错。@MOehm我没有说这是错的。这只是冗余和打字错误的另一个来源。这是主观的,与OP的问题毫无关系。你将卡片的副本存储在你的阵列中。我认为这个想法不是复制,而是存储指向其他地方已经存在的卡片的指针,也许是一个包含一副未缓冲的卡片的数组。因此,您可能应该通过card\u t*c
,然后分配new\u c=c
。(当对象较大或希望使用多个条件对数组进行排序时,这种间接排序技术特别有用。)您将a
和b
转换为const card\t**
,而不仅仅是card\t**
,这有什么具体原因吗?@luci88filter:如果可能的话,如果我不打算更改它们,那么最好保留指向const的指针。它“记录”变量的只读性质,如果指向的值意外更改,则会得到一个值。@Groo排序有效。问题是它正在更改卡片的地址。@Ilidam:好吧,排序似乎只起作用了,因为sizeof(card\u t*)
意外地等于机器上的sizeof(card\u t)
,所以幸运的是,指针交换时不会把所有事情搞糟。在卡片
中添加一个附加字段以测试我的理论。如果您有一个指针数组,qsort
将对该指针数组重新排序。这就是qsort
所做的。实际的卡不会在内存中移动。如果您在add\u card\u to
之外有一组额外的分配卡,并且您正在malloc
重新分配,这是另一个问题。如果没有实际完整的代码(a),就无法判断。
qsort(hand2->cards, hand2->n_cards, sizeof *hand2->cards, card_ptr_comp);
int card_ptr_comp(const void * a, const void * b)
{
const card_t* card_a = *(const card_t**)a;
const card_t* card_b = *(const card_t**)b;
return card_a->suit - card_b->suit;
}
card_t**
*deck .cards .n_cards
+------+ +--------+----+
| x---|------>| x | 3 |
+------+ +--------+----+ YOU ARE REORDERING THIS:
| card_t* card_t* card_t*
| +-----+-----+-----+
+------------->| x | y | z |
+-----+-----+-----+
.value .suit | | |
+----+---+ | | |
| | |<------+ | |
+----+---+ | |
| |
.value .suit | |
+----+---+ | |
| | |<------------+ |
+----+---+ |
|
.value .suit |
+----+---+ |
| | |<------------------+
+----+---+
void add_card_to(deck_t * deck, card_t * c)
{
deck->n_cards++;
deck->cards = realloc(...);
deck->cards[deck->n_cards - 1] = c;
}