[英]Sorting structure with C qsort()
难以理解实现C内置的qsort()来按存储的int值(hitCount)对结构数组进行排序的情况。
我的结构:
typedef struct words {
const char *word;
int hitCount;
} words;
我正在尝试使用Microsoft( http://support.microsoft.com/kb/73853 )给出的示例。
因此,我名列前茅:
typedef int (*compfn)(const void*, const void*);
和比较方法:
int compare (words *a, words *b) {
if (a->hitCount > b->hitCount) {
return -1;
} else if (a->hitCount < b->hitCount) {
return 1;
} else {
return 0;
}
}
然后在另一个方法中,我使用数组名称和其他详细信息调用qsort替换了Microsoft的示例:
qsort((void *) &output, outputLength, sizeof(words), (compfn)compare);
这给出了分段错误。
我不完全了解如何使用qsort,因此我假设我从Microsoft的示例改编了它,但是我做错了。
我希望我已经包含了错误,并且可以对我应该做些什么有所启发以使它正确地工作。
非常感谢!
您必须将数组而不是数组的地址传递给qsort。
qsort( output, ... );
同样,您的compare函数必须返回一个int并接受两个const void *参数。 将您的函数int compare (words *a, words *b)
强制转换为其他类型(但正确),然后由qsort()调用将导致不确定的行为。
比较函数必须为:
int compare (const void *a, const void *b)...
然后,将a和b强制转换为正确的类型:
((words*)a)->hitCount < ((words*)b)->hitCount
我怀疑outputLength计算不正确。 一个完整的工作示例:
#include <stdio.h>
#include <stdlib.h>
typedef struct words {
const char *word;
int hitCount;
} words;
int compare(const void * left, const void * right) {
const words * a = (const words *) left;
const words * b = (const words *) right;
if (a->hitCount > b->hitCount) {
return -1;
} else if (a->hitCount < b->hitCount) {
return 1;
} else {
return 0;
}
}
int main() {
struct words output[] = {
{ "hello", 314 },
{ "world", 42 },
{ "answer", 42 }
};
int outputLength = sizeof(output) / sizeof(output[0]);
int i;
output[0].word = "hello";
output[0].hitCount = 314;
output[1].word = "world";
output[1].hitCount = 42;
qsort(output, outputLength, sizeof(words), compare);
for (i = 0; i < outputLength; ++i) {
printf("%d %s\n", output[i].hitCount, output[i].word);
}
return 0;
}
标准库函数qsort
的原型是
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
注意compare
功能的签名。 您不能将指针转换为具有不同签名的函数并使它正常工作。 因此,类型转换您的比较功能将不起作用。 它必须具有与qsort
原型中声明的签名相同的签名。 将compare
功能更改为-
int compare(const void *a, const void *b) {
int c = ((words *) a)->hitCount;
int d = ((words *) b)->hitCount;
if(c > d) return -1;
if(c < d) return 1;
return 0;
}
qsort
的第一个参数base
址是包含要排序元素的缓冲区的基址。 此外,任何指针类型都可以与void *
变量赋值兼容,因此您无需强制转换基地址。 因此,您应该将qsort
函数称为-
qsort(output, outputLength, sizeof output[0], compare);
可以使用:
int compare (const void *a, const void *b) {
if (((words *)a)->hitCount > ((words *)b)->hitCount) {
return -1;
} else if (((words *)a)->hitCount < ((words *)b)->hitCount) {
return 1;
} else {
return 0;
}
}
并致电进行排序:
qsort(output, outputLength, sizeof(words), compare);
多亏了大家的帮助,但大多数还是归功于“自我”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.