Listing 4

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#define NUMELEM(a) (sizeof(a)/sizeof(a[0]))

struct tag1 {
   int m1;
   int m2;
   int m3;
};

struct tag2 {
   int m1;
   int m2;
};

int offset;  /*  int member offset for comparison */

main()
{
   int cmpstia(const void *, const void *);
   struct tag1 st1[] = {
      {1, 2, 3},
      {3, 1, 2},
      {2, 3, 1}
   };
   struct tag2 st2[] = {
      {7, 9},
      {5, 3},
      {2, 6},
      {6, 1}
   };
   int i;

/*  sort st1 on m1 */
   
   offset = offsetof(struct tag1, m1);
   qsort(&st1[0], NUMELEM(st1), sizeof(struct tag1), cmpstia);
   
   for (i = 0; i < NUMELEM(st1); ++i)
      printf("st1[%d]: %d, %d, %d\n", i, st1[i].m1,
         st1[i].m2, st1[i].m3);

/*  sort st1 on m3 */
   
   offset = offsetof(struct tag1, m3);
   qsort(&st1[0], NUMELEM(st1), sizeof(struct tag1), cmpstia);
   
   putchar('\n');
   for (i = 0; i < NUMELEM(st1); ++i)
      printf("st1[%d]: %d, %d, %d\n", i, st1[i].m1,
         st1[i].m2, st1[i].m3);

/*  sort st2 on m2 */
   
   offset = offsetof(struct tag2, m2);
   qsort(&st2[0], NUMELEM(st2), sizeof(struct tag2), cmpstia);
   
   putchar (' \n' );
   for (i = 0; i < NUMELEM(st2); ++i)
      printf("st2 [%d]: %d, %d\n", i, st2[i].m1, st2[i].m2);
   
   return 0;
}

/*  compare ints in ascending order */

int cmpstia(const void *pe1, const void *pe2)
{
   return *(int *)((char *)pe1 + offset) -
      *(int *)((char *)pe2 + offset);
}

st1[0]: 1, 2, 3
st1[1]: 2, 3, 1
st1[2]: 3, 1, 2

st1[0]: 2, 3, 1
st1[1]: 3, 1, 2
st1[2]: 1, 2, 3

st2[0]: 6, 1
st2[1]: 5, 3
st2[2]: 2, 6
st2[3]: 7, 9