I found this sample code online, which explains how the qsort
function works. I could not understand what the compare function returns.
#include
Whenever the sorting algorithm needs to find out which of two elements should be placed before the other, it will call the comparison function and pass pointers to the two elements. Since you are sorting int
values, the pointers are actually pointers to int
, but the signature must take void*
so that it can be used with any data type. Therefore, in order to obtain the actual element value, a
must be cast to int*
and then be dereferenced - hence, *(int*)a
. The function must return a negative value if a
is to be placed before b
, a positive value if b
is to be placed before a
, or zero if it doesn't matter which is placed first (which is usually the case when the elements are equal). In this particular case, since we are working with numbers, simply subtracting the value of b
from the value of a
is sufficient if we want the biggest numbers to go first.
a
and b
are being compared as integers - they have to be passed in as void *
but are then cast to int *
before finally being deferenced. As for the return value, it will either be positive, negative, or zero, all of which would be taken into account in the sorting function.
int cmpfunc (const void * a, const void * b) //what is it returning?
{
return ( *(int*)a - *(int*)b ); //What is a and b?
}
Is equivalent to:
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 );
}
qsort will give each pair it needs to compare to cmpfunc and uses it's return value to see which one is greater and then sorts the array accordingly.
Basically, if the compare function returns a positive result this means that the first argument is greater than the second one. Similarly, if it returns negative, then the second argument is greater.
In the example, we want to sort integers. So, we need to decide which one is greater when we compare two elements of the given array. To compare those, a simple substraction operation is enough since the result is positive when a is greater, 0 if a and b are equal and negative if b is greater.
What a
and b
are is clearly stated in the documentation for qsort
: these are pointers that point to array elements that have to be compared.
Comparison function in this case knows that the array elements are of type int
. So it casts the void *
pointers to int *
type and performs a tri-state comparison of the pointed int
values by subtracting the second from the first.
It will work properly for your set of values, but in general case using subtraction for tri-state comparison is a bad programming practice, since it is prone to overflow. Also, the function in your sample code unnecessarily casts away the constness of the pointed values.
A better alternative would be
int cmpfunc(const void *a, const void *b)
{
const int *A = a, *B = b;
return (*A > *B) - (*A < *B);
}
From http://en.cppreference.com/w/cpp/algorithm/qsort
The cmp
function returns a negative integer value if the first argument is less than the second,
a positive integer value if the first argument is greater than the second and zero if the arguments are equal.
The function takes void
pointers so the qsort
function may be used with any data type. However inside the cmp
function you must explicitly cast the pointer to the actual data type.