qsort()和转换操作

时间:2015-05-01 13:36:52

标签: c pointers struct casting qsort

考虑一系列指向结构的指针。以下代码取自您可能找到的示例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;

3 个答案:

答案 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。我要做的是对sp1sp2指针进行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函数的参数中获取数组的元素,这些参数需要被解除引用。