使用qsort()对包含字符串的结构体指针进行排序

6
我不确定使用qsort是否可以实现我的要求,因为我想要排序的是结构体指针数组,而我比较的却是字符串。
以下是程序摘要(假设在调用qsort()之前,所有学生数据都已存储在内存中,n是要排序的记录数):
struct student {
        char lname[NAMESIZE + 1];
        char fname[NAMESIZE + 1];
        short mid;
        short final;
        short hmwks;
};

int cmp(const void *, const void *);

int
main(int argc, char **argv)
{
        int n;
        struct student *data[MAX];

        qsort(data, n, sizeof(struct student *), cmp);

        return 0;
}

int
cmp(const void *p0, const void *p1)
{
        return strcmp((*(struct student *) p0).lname,
                      (*(struct student *) p1).lname);
}
3个回答

5

cmp()函数将接收到struct student**类型的参数(以void*的形式出现)。因此,需要按照以下方式修改cmp()函数:

int
cmp(const void *p0, const void *p1)
{
        struct student* ps0 = *(struct student**) p0;
        struct student* ps1 = *(struct student**) p1;

        return strcmp( ps0->lname, ps1->lname);
}

3
应该是这样的:
int
cmp(const void *p0, const void *p1)
{
        // pn is a pointer to an element of the array,
        // so, it's effectively a pointer to a pointer to a struct.
        // Therefore, we need to cast it appropriately to struct student **.
        // To get a pointer to a struct from it, we dereference it once,
        // hence the "*". Then we need to extract a pointer to the beginning
        // of a string, hence the "->".
        return strcmp((*(struct student **) p0)->lname,
                      (*(struct student **) p1)->lname);
}

谢谢,那解释了一切。 - Derek

1
其他答案都是正确的,但有一个小细节。我刚碰到这个问题,所以在这里留下来,以防其他人遇到极端严谨的编译器而感到困惑。 qsort() 比较函数接受两个 const void * 参数。这意味着当您取消引用它们以获取指向实际结构体的指针时,必须保留 const。因此,如果你想遵循C语言的每一条规则,你的代码应该像这样:
int
cmp(const void *p0, const void *p1)
{
    const struct student* ps0 = *(const struct student* const*) p0;
    const struct student* ps1 = *(const struct student* const*) p1;

    return strcmp(ps0->lname, ps1->lname);
}

注意 "const pointer to const" 结构-这告诉编译器您的原始指针(p0p1)在任何时候都不会失去其const性-您首先将它们解引用为const * const *,然后再解引用为const *。如果您仅使用const **,那么这是一个指向非const指针的const *,这将丢弃const void *的原始const性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接