Michael Mair wrote:
This is one of the reasons why one should never use typedef to
generate a "type" which is a pointer to something.
I wouldn't say "never".
For these type array sorting functions,
void sort(e_type *array, size_t nmemb);
typedefing pointer types when sorting arrays of pointers,
is no different from typdefing any other element type.
/* BEGIN ptr_sort.c */
/*
** lencomp() compares pointers to strings,
** according to string length.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define STRUCTURES 0 /* Either 1 or 0 */
#define SORT_FUNCTIONS { \
no_sort, "This is the original order of the test array:",\
si_sort, "Stable insertionsort:", \
s8sort, "Nonstable Shellsort, four is after " \
"nine, and eight is before three:", \
/*
q_sort, "Standard library qsort, " \
"unspecified ordering of equal keys:", \
*/}
#define NUMBERS { \
{"one"},{ "two"},{"three"},{"four"},{"five"}, \
{"six"},{"seven"},{"eight"},{"nine"},{ "ten"}, \
}
#define GT(A, B) (lencomp((A), (B)) > 0)
#define NMEMB (sizeof numbers / sizeof *numbers)
#define SORTS (sizeof s_F / sizeof *s_F)
#define str(s) # s
#define xstr(s) str(s)
#if STRUCTURES != 0
#define E_TYPE \
struct node { \
void *data; \
struct node *next; \
}
#else
#define E_TYPE char *
#endif
typedef E_TYPE e_type;
int lencomp(const void *, const void *);
void no_sort(e_type *, size_t);
void si_sort(e_type *, size_t);
void s8sort(e_type *, size_t);
void q_sort(e_type *, size_t);
int main(void)
{
size_t element, sort;
struct sf {
void (*function)(e_type *, size_t);
const char *description;
} s_F[] = SORT_FUNCTIONS;
const e_type numbers[] = NUMBERS;
e_type copy[NMEMB];
puts("/* BEGIN output from ptr_sort.c */\n\nArrays of type "
xstr(E_TYPE) ",\nare being sorted by string length.");
for (sort = 0; sort != SORTS; ++sort) {
putchar('\n');
puts(s_F[sort].description);
memcpy(copy, numbers, sizeof copy);
s_F[sort].function(copy, NMEMB);
for (element = 0; element != NMEMB; ++element) {
#if STRUCTURES != 0
puts(copy[element].data);
#else
puts(copy[element]);
#endif
}
}
puts("\n/* END output from ptr_sort.c */");
return 0;
}
int lencomp(const void *a, const void *b)
{
#if STRUCTURES != 0
const size_t a_len = strlen((*(e_type*)a).data);
const size_t b_len = strlen((*(e_type*)b).data);
#else
const size_t a_len = strlen(*(e_type*)a);
const size_t b_len = strlen(*(e_type*)b);
#endif
return b_len > a_len ? -1 : a_len != b_len;
}
void no_sort(e_type *array, size_t nmemb)
{
array || nmemb;
}
void si_sort(e_type *array, size_t nmemb)
{
e_type temp, *base, *low, *high;
if (nmemb > 1) {
--nmemb;
base = array;
do {
low = array++;
if (GT(low, array)) {
high = array;
temp = *high;
do {
*high-- = *low;
if (low == base) {
break;
}
--low;
} while (GT(low, &temp));
*high = temp;
}
} while (--nmemb != 0);
}
}
void s8sort(e_type *array, size_t nmemb)
{
e_type temp, *i, *j, *k, *after;
after = array + nmemb;
if (nmemb > (size_t)-1 / 3) {
nmemb /= 3;
}
do {
for (i = array + nmemb; after != i; ++i) {
j = i - nmemb;
if (GT(j, i)) {
k = i;
temp = *k;
do {
*k = *j;
k = j;
if (nmemb + array > j) {
break;
}
j -= nmemb;
} while (GT(j, &temp));
*k = temp;
}
}
nmemb = nmemb != 2 ? 3 * nmemb / 8 : 1;
} while (nmemb != 0);
}
void q_sort(e_type *array, size_t nmemb)
{
qsort(array, nmemb, sizeof *array, lencomp);
}
/* END ptr_sort.c */