我在网上找到了这个示例代码,它解释了qsort
函数的工作原理。我无法理解比较函数返回的内容。
#include "stdlib.h"
int values[] = { 88, 56, 100, 2, 25 };
int cmpfunc (const void * a, const void * b) //what is it returning?
{
return ( *(int*)a - *(int*)b ); //What is a and b?
}
int main(int argc, _TCHAR* argv[])
{
int n;
printf("Before sorting the list is: \n");
for( n = 0 ; n < 5; n++ ) {
printf("%d ", values[n]);
}
qsort(values, 5, sizeof(int), cmpfunc);
printf("\nAfter sorting the list is: \n");
for( n = 0 ; n < 5; n++ ) {
printf("%d ", values[n]);
}
return 0;
}
答案 0 :(得分:8)
int cmpfunc (const void * a, const void * b) //what is it returning?
{
return ( *(int*)a - *(int*)b ); //What is a and b?
}
相当于:
int cmpfunc (const void * a, const void * b) //what is it returning?
{
// qsort() passes in `void*` types because it can't know the actual types being sorted
// convert those pointers to pointers to int and deref them to get the actual int values
int val1 = *(int*)a;
int val2 = *(int*)b;
// qsort() expects the comparison function to return:
//
// a negative result if val1 < val2
// 0 if val1 == val2
// a positive result if val1 > val2
return ( val1 - val2 );
}
答案 1 :(得分:3)
a
的文档中明确说明了b
和qsort
的内容:这些是指向必须比较的数组元素的指针。
在这种情况下,比较函数知道数组元素的类型为int
。因此,它将void *
指针转换为int *
类型,并通过从第一个值中减去第二个来执行指向int
值的三态比较。
它适用于您的值集,但一般情况下使用减法进行三态比较是一种糟糕的编程习惯,因为它容易溢出。此外,示例代码中的函数不必要地抛弃了指向值的常量。
更好的选择是
int cmpfunc(const void *a, const void *b)
{
const int *A = a, *B = b;
return (*A > *B) - (*A < *B);
}
答案 2 :(得分:2)
每当排序算法需要找出两个元素中的哪一个应该放在另一个之前时,它将调用比较函数并将指针传递给这两个元素。由于您要对int
值进行排序,因此指针实际上是指向int
的指针,但签名必须采用void*
,以便它可以与任何数据类型一起使用。因此,为了获得实际元素值,必须将a
强制转换为int*
,然后将其解除引用 - 因此,*(int*)a
。如果a
放在b
之前,则函数必须返回负值;如果要b
放置a
,则返回正值;如果不放置b
则返回0 39;首先放置的东西(通常是元素相等时的情况)。在这种特殊情况下,由于我们正在处理数字,因此如果我们希望将最大数字放在第一位,只需从a
的值中减去{{1}}的值即可。
答案 3 :(得分:2)
来自http://en.cppreference.com/w/cpp/algorithm/qsort
如果第一个参数小于第二个参数,cmp
函数返回一个负整数值,
如果第一个参数大于第二个参数,则为正整数值;如果参数相等,则为零。
该函数使用void
指针,因此qsort
函数可以与任何数据类型一起使用。但是在cmp
函数内部,您必须显式地将指针强制转换为实际数据类型。
答案 4 :(得分:1)
a
和b
被比较为整数 - 它们必须以void *
传递,但在最终被推崇之前被投射到int *
。至于返回值,它将是正数,负数或零,所有这些都将在排序函数中考虑。
答案 5 :(得分:0)
qsort会给它需要与cmpfunc进行比较的每一对,并使用它的返回值来查看哪一个更大,然后相应地对数组进行排序。
基本上,如果compare函数返回肯定结果,则意味着第一个参数大于第二个参数。同样,如果它返回负数,那么第二个参数更大。
在示例中,我们要对整数进行排序。因此,当我们比较给定数组的两个元素时,我们需要决定哪一个更大。为了比较这些,一个简单的减法操作就足够了,因为当a更大时结果为正,如果a和b相等则为0,如果b更大则为负。