无法深入实现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;
}
}
然后在另一个方法中,我使用我的数组名称和其他详细信息替换Microsoft示例调用qsort:
qsort((void *) &output, outputLength, sizeof(words), (compfn)compare);
这会产生分段错误。
我不完全了解如何使用qsort所以我假设我从微软的例子中调整了它我做错了。
我希望我已经包含了这个错误,并且可以获得一些关于我应该做什么的启示,以使其正常工作。
非常感谢!
答案 0 :(得分:3)
您必须将数组而不是数组的地址传递给qsort。
qsort( output, ... );
此外,您的比较函数必须返回一个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
答案 1 :(得分:1)
我怀疑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;
}
答案 2 :(得分:1)
标准库函数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;
}
base
的第一个参数qsort
是包含要排序的元素的缓冲区的基址。此外,任何指针类型都与void *
变量兼容,因此您无需转换基址。因此,您应该将qsort
函数称为 -
qsort(output, outputLength, sizeof output[0], compare);
答案 3 :(得分:0)
使用它:
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);
感谢大家的帮助,但多数人都归功于“自我”。