我尝试编写用于对int数组进行qsorting的compare函数。并给出正确的升序结果。但是对于降序不正确。为什么?什么是正确的compare int函数?
int compare(const void *a, const void *b){
int x = *(int*)a;
int y = *(int*)b;
return (x > y) - (x < y);
}
int reverse(const void *a, const void *b){
return -compare(a, b);
}
int main(){
int x[] = {500, 456, 18, 13, 3, 89, 800, 6874};
qsort(x, sizeof(x[0]), sizeof(x)/sizeof(x[0]), reverse);
for (int i=0; i < sizeof(x)/sizeof(x[0]); i++){
printf("%d\n", x[i]);
return 0;
}
我期望打印的整数从大6874到最小3的降序。 但是我收到了:
800 6874 500 456 18岁 13 3 89
答案 0 :(得分:4)
您已经交换了qsort的第二个和第三个参数-应该是
qsort(x, sizeof(x)/sizeof(x[0]), sizeof(x[0]), reverse);
调用它的方式,因为您的计算机上数组恰好是8个元素,而sizeof(int)恰好是4个,所以它是根据每个对的第一个int对int进行排序的。
答案 1 :(得分:0)
在处理其他方面之前,您已经将第二个和第三个参数切换为qsort(3)
,第一个是数组指针,第二个是元素数量,第三个是大小,第四个是比较函数指针。为了使qsort(3)
更好,您首先需要按正确的顺序放置参数:)
。
好吧,如果compare()
小于< 0
,a
(而不是+1),b
函数必须返回> 0
(不是-1) a
大于b
,并且在a
和b
相等的情况下为零。您的公式是正确的,但是表达式有些复杂,因为只需将两个参数相减即可实现。如果检查strcpy(3)
的返回值有多少种实现(嗯,不是全部,但是有很多)是两个字符串不同的位置处的char码之间的差异,这足以进行有效的实现。
顺便说一句,您知道void *
是与任何其他指针类型兼容的指针,因此编写比较函数(基于对整数的引用而不是基于它们的值)的最佳方法之一是像这样写:
int compare(int *a, int *b)
{
return *a - *b;
}
int reverse_compare(int *a, int *b)
{
return -compare(a, b);
}
(在调用qsort(3)
时会收到可忽略的警告)甚至更简单
int reverse_compare(int *a, int *b)
{
return compare(b, a);
}
,然后将其直接传递到qsort(3)
。确实,反向比较只需要两个指针,并且可以通过将其编写为以下形式使其完全通用:
int reverse_compare(const void *a, const void *b)
{
return compare(b, a);
}
如果检查以下示例,您将看到reverse
是传递给qsort
的例程(参数匹配时没有警告,并且reverse
主体内没有警告在对void *
的调用中将它们转换为compare_int
时。)
#include <stdlib.h>
#include <stdio.h>
int compare_int(const int *a, const int *b)
{
return (*a > *b) - (*b > *a);
}
int reverse(const void *a, const void *b)
{
return compare_int(b, a);
}
int main()
{
int x[] = {500, 456, 18, 13, 3, 89, 800,
6874};
qsort(x,
sizeof(x)/sizeof(x[0]),
sizeof(x[0]),
reverse);
for (int i=0; i <
sizeof(x)/sizeof(x[0]); i++) {
printf("%d\n", x[i]);
}
return 0;
}