Programming Problems Using Heap Memory 135
is in another part of memory that stores the compiled program’s instructions. The
instructions must have addresses because they are stored in memory. Every line of
a program is stored at a memory location. Thus, it is possible to use an address to
specify a particular line of a program. By convention, C uses the name of a function as
the address of the first line of a function. This is the reason a function can be expressed
by a pointer: The function name is the address of the first line of that function.
3. The passed function takes two input arguments. Each argument stores an address.
Again, void * means that the address can be of any type. Section 7.1.7 explains
the meaning of const. This function cannot change the value stored at the address
because const is in front of the type (even though the type is void).
Putting all these factors together, the comparison function must have the following type:
int compare func ( const void * a , const void * b)1
9.2.2 The Comparison Function
What is the comparison function? Why is it necessary to provide a comparison function
as an argument to qsort? The goal of qsort is to sort arrays of any type. This means that
qsort needs to know how to compare two elements in an array without knowing the type.
This is not possible automatically because different types have different sizes. Moreover,
when we talk about programmer-defined structures later in this book, one structure may
contain multiple attributes. It is impossible for qsort to know how to compare programmer-
defined structures. To make it possible, programmers have to tell qsort how to compare
the elements. The comparison function can decide ascending or descending order. The com-
parison function must have the following structure:
// co m parefunc . c1
int compare func ( const void * arg1 , const void * arg2 )2
{3
// convert void * to a known type ( int , char , double ...)4
const type * ptr1 = ( const type *) arg1 ;5
const type * ptr2 = ( const type *) arg2 ;6
// get the value from the address7
const type val1 = * ptr1 ;8
const type val2 = * ptr2 ;9
// compare the value10
i f ( val1 < val2 )11
{ return -1; }12
i f ( val1 == val2 )13
{ return 0; }14
return 1;15
}16
The comparison function has three steps:
1. The arguments arg1 and arg2 point to two distinct elements in the array. If we are
sorting an array of integers, then the array elements are of type int. The pointers
to those elements must be int *. In lines 5 and 6 we convert arg1 and arg2 to the
correct type. This is called type casting. The qsort function knows the size of each
array element because the third argument provides that information.
2. After type casting, ptr1 and ptr2 have the same value (point to the same addresses)
as arg1 and arg2 respectively. The comparison function can now access the data at
those memory locations because the function has changed the pointers to the known