qsort() - HELP

Mark Brader msb at sq.sq.com
Wed Feb 21 06:01:43 AEST 1990


> >	   void qsort(base, nel, width, compar)
> >	   char *base
> >	   unsigned nel, width
> >	   int (*compar)()
> Yep, 'base' is supposed to the be the (char *)base of the array you
> intend to sort. 'nel' is the number of elements to be sorted and
> 'width' the sizeof(element_to_sort).
> 'compar' is a pointer to int function that must behave like strcmp...
> If is strings you want to sort might just call (I think):
> 		qsort(array,nel,width,strcmp).

This is correct as far as it goes but there is a tricky point that
must be emphasized.  The compar function that you provide will be
called with arguments that *point to* the elements of the array.
(It works this way because the array elements might have a type that
cannot be passed efficiently, or at all, as a function argument.)

Therefore, if you have a 2-dimensional array of chars where each row
is used to contain a string, like this:

	char place[][MAXLEN+1] = {"Portugal", "Canada", "Paraguay", "Japan"};

then you can indeed sort it with

	#define NUMEL(x) (sizeof x / sizeof *x)
	int strcmp();
	qsort ((char *) place, NUMEL (place), sizeof *place, strcmp);

However, if your array itself contains pointers, like this:

	char *place[] = {"Portugal", "Canada", "Paraguay", "Japan"};

then you must define a function

	int
	indstrcmp (sp1, sp2)
	char *sp1, *sp2;
	{
		return strcmp ( * (char **) sp1,  * (char **) sp2);
	}

The arguments to indstrcmp() have to be declared as char * rather than
char **, and then converted to char **,, because char * is what qsort()
is going to pass to indstrcmp().

and invoke qsort using it:

	qsort ((char *) place, NUMEL (place), sizeof *place, indstrcmp);


All of the above is in pre-ANSI style.  In ANSI C, void * rather than char *
is used as the generic pointer type (but they're represented the same way
and passed the same way to functions, so strcmp() will work on void *'s).
So the first example becomes:

	qsort ((void *) place, NUMEL (place), sizeof *place, strcmp);

and the second one:

	int
	indstrcmp (const void *sp1, const void *sp2)
	{
		return strcmp ( * (char **) sp1, * (char **) sp2);
	}
and:
	qsort ((void *) place, NUMEL (place), sizeof *place, indstrcmp);

Followups are directed to comp.lang.c.
-- 
Mark Brader			"[This computation] assumed that everything
SoftQuad Inc., Toronto		 would work, a happy state of affairs found
utzoo!sq!msb, msb at sq.com	 only in fiction."	-- Tom Clancy

This article is in the public domain.



More information about the Comp.lang.c mailing list