为什么按降序排列的 qsort int 数组不正确?
Why qsort int array in descending order is incorrect?
我尝试编写用于对 int 数组进行 qsorting 的比较函数。它给出了升序的正确结果。但是对于降序是不正确的。为什么?什么是正确的 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
您已经交换了 qsort 的第二个和第三个参数 -- 它应该是
qsort(x, sizeof(x)/sizeof(x[0]), sizeof(x[0]), reverse);
你调用它的方式,因为你的数组恰好是 8 个元素,而 sizeof(int) 在你的机器上恰好是 4,它是根据每对的第一个整数对整数对进行排序。
在处理其他方面之前,你已经将第二个和第三个参数切换为qsort(3)
第一个是数组指针,第二个是元素个数,第三个是大小,第四个是比较函数指针。要做好 qsort(3)
你首先需要把参数放在正确的顺序 :)
.
嗯,compare()
函数必须return< 0
(不是-1)如果a
小于b
,> 0
(而不是 +1) 如果 a
大于 b
并且如果 a
和 b
相等则为零。你的公式是正确的,但有点过于复杂的表达,因为可以通过减去两个参数来实现。如果你检查 strcpy(3)
的许多实现做了什么 return (嗯,不是全部,但很多)是两个字符串不同位置的字符代码之间的差异,这足以进行有效的实现。
顺便说一句,你知道 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);
}
pru.c
如果检查以下示例,您会看到 reverse
是传递给 qsort
的例程(没有警告,因为参数匹配,并且 [=30 的正文中没有警告=] 在对 compare_int
的调用中将它们转换为 void *
时。)
#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;
}
我尝试编写用于对 int 数组进行 qsorting 的比较函数。它给出了升序的正确结果。但是对于降序是不正确的。为什么?什么是正确的 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
您已经交换了 qsort 的第二个和第三个参数 -- 它应该是
qsort(x, sizeof(x)/sizeof(x[0]), sizeof(x[0]), reverse);
你调用它的方式,因为你的数组恰好是 8 个元素,而 sizeof(int) 在你的机器上恰好是 4,它是根据每对的第一个整数对整数对进行排序。
在处理其他方面之前,你已经将第二个和第三个参数切换为qsort(3)
第一个是数组指针,第二个是元素个数,第三个是大小,第四个是比较函数指针。要做好 qsort(3)
你首先需要把参数放在正确的顺序 :)
.
嗯,compare()
函数必须return< 0
(不是-1)如果a
小于b
,> 0
(而不是 +1) 如果 a
大于 b
并且如果 a
和 b
相等则为零。你的公式是正确的,但有点过于复杂的表达,因为可以通过减去两个参数来实现。如果你检查 strcpy(3)
的许多实现做了什么 return (嗯,不是全部,但很多)是两个字符串不同位置的字符代码之间的差异,这足以进行有效的实现。
顺便说一句,你知道 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);
}
pru.c
如果检查以下示例,您会看到 reverse
是传递给 qsort
的例程(没有警告,因为参数匹配,并且 [=30 的正文中没有警告=] 在对 compare_int
的调用中将它们转换为 void *
时。)
#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;
}