How is qsort able to take in any array types and sort it?

Viewed 37

qsort has the following function protype

void qsort(
    void*  _Base,
    size_t _NumOfElements,
    size_t _SizeOfElements,
    _CompareFunction
    );

How is it possible that it is able to sort any array types (int, double, char, etc.)? How does qsort know the type of array that I am asking it to sort?

1 Answers

It is due to the comparison function that casts void pointers to required types when it compares elements of the array.

Here is a demonstration program.

#include <stdio.h>
#include <stdlib.h>

int cmp( const void *px, const void *py )
{
    int x = *( const int * )px;
    int y = *( const int * )py;

    return ( y < x ) - ( x < y );
}

int main( void ) 
{

    int a[] ={5, 3, 1, 9, 8, 2, 4, 7};
    const size_t N = sizeof( a ) / sizeof( *a );

    for (size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );

    qsort( a, N, sizeof( *a ), cmp );
    
    for (size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );
}

The program output is

5 3 1 9 8 2 4 7 
1 2 3 4 5 7 8 9 

As you can see within the comparison function cmp the passed pointers are casted to the required type.

int x = *( const int * )px;
int y = *( const int * )py;

To traverse the array the function qsort uses the pointer arithmetic the following way. Initially the pointer _Base points to the first element of the passed array. To move for example the pointer to the i-th element of the array it does something like the following

void *ith_element_ptr = ( char * )_Base + i * _SizeOfElements;
Related