考虑一系列指向结构的指针。以下代码取自您可能找到的示例here。我想对这两排铸造进行解释。我不熟悉这个"双重铸造"。
int myptrstructcmp(const void *p1, const void *p2)
{
struct mystruct *sp1 = *(struct mystruct * const *)p1;
struct mystruct *sp2 = *(struct mystruct * const *)p2;
我认为应该是:
int myptrstructcmp(const void *p1, const void *p2)
{
struct mystruct *sp1 = (struct mystruct *)p1;
struct mystruct *sp2 = (struct mystruct *)p2;
答案 0 :(得分:5)
假设您正在排序int
的数组。你的比较器会传递一对int *
伪装成void *
;添加了一个间接级别。
如果要对struct mystruct *
数组进行排序,则比较器将struct mystruct **
伪装成void *
;添加了一个间接级别。
struct mystruct * const *
的含义是什么?如果没有const*
则无法正确投射。为什么呢?
Whaddya的意思是'没有const *
它无法正确投射'?没有const
,它可以正常工作。没有第二个*
,它不起作用,因为函数传递struct mystruct **
(给出或取一些常量),如果省略第二个星,则表示你正在滥用类型系统。 / p>
考虑:
struct mystruct
{
int i;
};
int myptrstructcmp(const void *p1, const void *p2);
int myptrstructcmp(const void *p1, const void *p2)
{
struct mystruct *sp1 = *(struct mystruct **)p1;
struct mystruct *sp2 = *(struct mystruct **)p2;
if (sp1->i < sp2->i)
return -1;
else if (sp1->i > sp2->i)
return +1;
else
return 0;
}
编译好。在const
之间添加**
时,它也可以正常编译。就个人而言,我不会在演员表中加入const
。我要做的是对sp1
和sp2
指针进行const限定:
struct mystruct const *sp1 = *(struct mystruct **)p1;
struct mystruct const *sp2 = *(struct mystruct **)p2;
或:
const struct mystruct *sp1 = *(struct mystruct **)p1;
const struct mystruct *sp2 = *(struct mystruct **)p2;
这承诺不会修改它们在函数中指向的对象,这对qsort()
的正确性能至关重要。
答案 1 :(得分:3)
这是你的线索 - 在你引用的C FAQ中:
另一方面,如果您要对结构进行排序,则需要间接,
您正在排序指向结构的指针列表。指针必须通过排序在列表中进行处理,这意味着您通过引用(通过指向指针的指针)传递列表中的指针以进行比较。
答案 2 :(得分:2)
来自man qsort
:
[...]比较函数[..],用两个指向被比较对象的参数调用。
“被比较的对象”是传递给qsort()
的数组的元素,并且这个要排序的数组包含指针,比较函数接收指针指针作为参数。
要从传递给comparsion函数的参数中获取数组的元素,这些参数需要被解除引用。