General Comparison Functions in C

 

Introduction

`qsort`, `heapsort`, `mergesort`, `bsearch`, and many more search and sort functions all take a `compar` argument to determine the sorting order of elements in an array. The `compar` function takes the form `int (*compar)(const void *, const void *)`. The `compar` function’s parameters are the address of two of the elements in the array. The parameters will need to be dereferenced before they can be compared. Any type of value can have a `compar` function written for it and it can be used to sort an array of any type.

Common Compared Types

Strings and integers are two of the most common types that need to be sorted. Since the dereference requirement tends to trip people up, here are sort functions for these two types.

static int string_cmp(const void *a, const void *b)
{
	const char *sa = *(const char **)a;
	const char *sb = *(const char **)b;

	return strcmp(sa, sb);
}
static int int_cmp(const void *a, const void *b)
{
	int ia = *(int *)a;
	int ib = *(int *)b;

	if (ia == ib)
		return 0;
	if (ia > ib)
		return 1;
	return -1;
}

Example

Using the above comparison functions is really easy. We just need to pass the function as the `compar` argument to the sort or search function.

int main(int argc, char **argv)
{
	size_t i;
	int    aints[]  = { 9, 7, 8, 1, 2, 4, 10, 9 };
	char  *mystrs[] = { "abc", "1", "a", "c", "dog", "cat", "bat", "xyz" };

	qsort(aints, sizeof(aints)/sizeof(*aints), sizeof(*aints), int_cmp);
	for (i=0; i<sizeof(aints)/sizeof(*aints); i++) {
		printf("%dn", aints[i]);
	}

	printf("---n");

	qsort(mystrs, sizeof(mystrs)/sizeof(*mystrs), sizeof(*mystrs), string_cmp);
	for (i=0; i<sizeof(mystrs)/sizeof(*mystrs); i++) {
		printf("%sn", mystrs[i]);
	}
	return 0;
}