Programming Problems Using Recursion 231
}103
return arr ;104
}105
void printArr a y ( i n t * arr , in t len )106
{107
int ind ;108
int sorted = 1;109
for ( ind = 0; ind < len ; ind ++)110
{111
#i f d e f DEBUG112
printf (" %d ", arr [ ind ]) ;113
#e ndif114
i f (( ind > 0) && ( arr [ ind ] < arr [ ind -1]) )115
{116
sorted = 0;117
}118
}119
printf (" nsorted = % dn n " , sorted ) ;120
}121
This implementation introduces a new way to debug. Lines 17 and 19 use #ifdef DEBUG
and #endif to enclose debugging code. If this program is compiled the normal way, the lines
between #ifdef DEBUG and #endif are skipped by the compiler. In other words, the line
(or lines) between #ifdef DEBUG and #endif has (or have) no effect. This is useful if the
program prints too many debugging messages. If you want to see the debugging messages,
compile the program in the following way:
$ gcc -g -Wall -Wshadow -DDEBUG quicksort.c -o quicksort
When adding -DDEBUG (it is -D followed by the symbol after #ifdef) after gcc, the
debugging messages are shown. This flag tells gcc to define the symbol DEBUG. You can
define other symbols by adding -D in front of the symbol after the gcc command. It is also
possible to add -DDEBUG to CFLAGS in Makefile.
You may have noticed that the function printArray also checks whether the array is
sorted. This is another debugging technique. Visually inspecting whether an array is sorted
is useful for an array with only a few elements. Instead of using visual inspection, the
program automatically determines whether or not the array is sorted. Making the program
check for its own correctness allows us to test quickSort and its helper function with an
array of thousands of elements.
Another debugging technique is to use argv[2] to set the seed of the random numbers.
To test the program, you probably want to use random numbers so that the tests can cover
different scenarios. However, we need some way to repeat the test if a problem is found, and
that means we must be able to control the sequence of random numbers. One solution is to
use a command-line argument. If this argument is present, the random number generator
is seeded correspondingly, and then the same sequence of numbers is generated. Without
giving this command-line argument, the seed is determined by the system clock, and the
sequence will almost certainly be different every time the program is run.
At first glance, this program may appear straightforward. A closer look, however, re-
veals that some common mistakes can easily occur. The helper function’s second and third
arguments specify the range of indexes that is being sorted. This function assumes last is
a valid index and quickSort thus must use len - 1. If line 51 uses len, then the program
may access an invalid memory location because len is not a valid index. As explained in