使用 qsort() 对指向包含字符串的结构的指针进行排序
Posted
技术标签:
【中文标题】使用 qsort() 对指向包含字符串的结构的指针进行排序【英文标题】:using qsort() to sort pointers to structs containing strings 【发布时间】:2012-05-13 15:53:01 【问题描述】:我不确定这是否可以用 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);
【问题讨论】:
【参考方案1】:将传递给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);
【讨论】:
【参考方案2】:应该是这样的:
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);
【讨论】:
谢谢,这解释了一切【参考方案3】:除了一个小细节之外,其他答案都是正确的。我刚刚遇到了这个问题,所以我将把它留在这里,以防其他人发现自己正在为一个极其迂腐的编译器而苦苦挣扎。
qsort()
比较器接受两个const void *
参数。这意味着当您取消引用它们以获取指向实际结构的指针时,您必须保留 const
-ness。因此,如果您要遵循 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 指向 const 的指针”结构——这是你告诉编译器你的原始指针(p0
和 p1
)在任何时候都不会丢失它们的 const
-ness——你首先将它们取消引用到 @987654328 @,然后将其取消引用到 const *
。如果你简单地使用const **
,那是一个const *
到*
(非const
)的指针,它丢弃了const
的原始const void *
。
【讨论】:
以上是关于使用 qsort() 对指向包含字符串的结构的指针进行排序的主要内容,如果未能解决你的问题,请参考以下文章