Solution for Exercise 09_02-sortstruct.c

09_02-sortstruct.c

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

/* must define the structure externally */
struct person {
	char name[16];
	int age;
};

/* the structure is complex, so it helps
   here to unwind it before making the
   comparison */
int compare(const void *a, const void *b)
{
	/* unique structure pointers */
	struct person *alpha;
	struct person *beta;
	int result;

	/* assign our structure pointers to the
	   void pointers */
	alpha = (struct person *)a;
	beta = (struct person *)b;
	/* calculate the result */
	result = alpha->age - beta->age;
	return( result );
}

int main()
{
	int size,x;
	struct person people[] = {
		{ "Adam", 32 },
		{ "Barbara", 26 },
		{ "Charlie", 51 },
		{ "Diane", 18 },
		{ "Edmond", 39 },
		{ "Fanny", 6 }
	};
	
	/* obtain array size */
	size = sizeof(people)/sizeof(people[0]);

	/* output original */
	puts("Original array:");
	for( x=0; xlt;size; x++ )
		printf("%s is %d\n",
				people[x].name,
				people[x].age
			  );

	/* quick sort */
	qsort( people, size, sizeof(struct person), compare );

	/* output sorted */
	puts("Sorted array:");
	for( x=0; x<size; x++ )
		printf("%s is %d\n",
				people[x].name,
				people[x].age
			  );

	return 0;
}

Output

Original array:
Adam is 32
Barbara is 26
Charlie is 51
Diane is 18
Edmond is 39
Fanny is 6
Sorted array:
Fanny is 6
Diane is 18
Barbara is 26
Adam is 32
Edmond is 39
Charlie is 51

Notes

* No pointers are allocated in this code. Only the compare() function (and qsort()) uses pointers, as described in the book. Therefore, nothing needs to be freed.

* To convince the comipler that the pointers passed to the compare() function reference structure, two person structure pointers are declared: struct person *alpha; and struct person *beta;

* Each pointer, alpha and beta, are assigned the void pointer arguments a and b, with a cast of (struct person *) to convince the compiler that these void types hold person structures. The goal is to use alpha and beta in the function instead of creating some weird casting monster that no one can read.

* Once pointers alpha and beta are set, their two age members are compared. As these are pointers, the -> operator is used: result = alpha->age = beta->age Variable result is returned.

* Even when you fully understand pointers, I recommend breaking down their operation as shown in this code. It saves time and confusion over complex typecasting.