I want to sort struct
array but while understand the logic of compare function i stuck my confusion is how compare function is work when it call in qsort()
function without passing argument
Using GCC on Code Block on windows:
Code
int compare(const void * a, const void * b);
struct cricketers
{
int avrun;
char name[30];
int age;
int notm;
}india[Max] = {
122, "Sachin Tendulkar", 30, 67,
97, "Virendra Sehwag", 35, 56,
66, "Irfan Pathan", 32, 45,
153, "Yusuf Pathan", 36, 21,
101, "Yuvaraj Singh", 32, 45,
};
int main()
{
int i;
qsort(india, 5, sizeof(struct cricketers), compare);
for (i = 0; i < 5; i++)
{
printf("Name : %s", india[i].name);
printf("\nAge : %d", india[i].age);
printf("\nTotal Test Matches played : %d", india[i].notm);
printf("\nAverage Run : %d\n\n\n", india[i].avrun);
}
_getch();
return 0;
}
int compare(const void * a, const void * b)
{
return (*(int*)a - *(int*)b);
}
It is the function qsort
that internally calls the comparison function passing to it void pointers to two elements of the array.
According to the C Standard (6.7.2.1 Structure and union specifiers) the address of the first member of a structure is equal to the address of the whole object of the structure type.
15 Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.
So the value for example of the parameter a
casted to the type int *
yields the address of the data member int avrun
of the structure.
Nevertheless this expression (*(int*)a - *(int*)b)
can invoke undefined behavior due to overfloating of signed integers.
I would write the comparison function the following way.
int compare( const void *a, const void *b )
{
const struct cricketers *left = ( const struct cricketers * )a;
const struct cricketers *right = ( const struct cricketers * )b;
return ( right->avrun < left->avrun ) - ( left->avrun < right->avrun );
}