using the qsort() function
I'm a student & i looked up this function in a book. It works as it should but i don't quite understand the inner workings of the sortFunction()
which is passed to the qsort()
function. If some one could explain it in detail, please do. Thanks in advance.
#include<iostream>
#include<stdlib.h>
using namespace std;
//form of sort function required by qsort()
int sortFunction(const void *intOne,const void *intTwo);
const int tableSize = 10;
int main()
{
int i, table[tableSize];
//fill the table with values
for(i = 0; i < ta开发者_StackOverflowbleSize; i++)
{
cout << "Enter value " << (i + 1) << " : ";
cin >> table[i];
}
cout << "\n";
//sort values
qsort((void*)table, tableSize, sizeof(table[0]), sortFunction);
//print the results
for(i = 0; i < tableSize; i++)
{
cout << "Value " << (i + 1) << " : " << table[i] << endl;
}
cout << "\nDone\n";
return 0;
}
int sortFunction(const void *a, const void *b)
{
int intOne = *((int*)a);
int intTwo = *((int*)b);
if (intOne < intTwo)
{
return -1;
}
if (intOne == intTwo)
{
return 0;
}
return 1;
}
If you look at the actual call to qsort
...
qsort((void*)table, tableSize, sizeof table[0], sortFunction);
...you'll see it provides:
- a
void*
address and the size (in bytes) of the entire data array to be sorted, then - the size of one data element in that array, then
- a pointer to the comparison function "sortFunction".
There's no argument passed that allows qsort
to know what the type of the element is - i.e. how the individual bits in any single data element are used to represent some data value - so there's no way qsort
can meaningfully compare two such elements. When you supply...
int sortFunction(const void *a, const void *b)
{
int intOne = *((int*)a);
int intTwo = *((int*)b);
...and qsort
calls it, you're getting two pointers - they're to memory addresses but when qsort
calls sortFunction
those void
pointers still tell you nothing about the data element type, as qsort
has no insight itself to pass along. The last two lines of code above are where you - the programmer coordinating the qsort
call - reapply the knowledge you've had all along about what the data element type is: in this case, they're int
s, so you cast each void*
to an int*
(using (int*)a
), then dereference that int*
to get the int
at memory address a
. Similarly for b
. In doing so, you've recovered the two numbers that were there as numbers. Then, the job of sortFunction
is to indicate how they should be ordered when sorting finishes. To indicate that a
should be first, sortFunction
can return any negative value (e.g. -1
); if they're equivalent, return 0;
, and if b
should be first, return any positive value (e.g. 1
). qsort()
receives that information and uses it to work out how to shuffle the data elements around as it sorts.
FWIW, C lets you express that a bit more succinctly as...
return intOne < intTwo ? -1 :
intOne == intTwo ? 0 :
1;
...or (faster, but relying on boolean comparison results being 0 and 1, which may confuse some programmers reading your code)...
return (intOne > intTwo) - (intOne < intTwo);
...or, if you're sure the following can never be mathematically less than INT_MIN
(such values wrap around to a big positive number inappropriately)...
return intOne - intTwo;
sortFunction
isn't actually doing the sorting, it is being used as a comparison function to determine whether one element should precede another in the sorted list.
What you called 'sortFunction' is normally called a comparator. It basically tells the generic sort code in qsort()
whether two elements in the array being sorted compare equal (0), or whether the first argument sorts before the second (<0) or the first argument sorts after the second (>0).
With that information, plus the size of each row, plus the number of rows in the array and the start of the array, the qsort()
function can order the data correctly.
As you can see in documentation, qsort function takes a comparator as it's last parameter. This function is used to actually compare parameters (tell which one should go first in a sorted array).
精彩评论