/* 08May24: Demonstration der Libc funktion qsort(3).
 *
 * Siehe auch: https://wwwcip.cs.fau.de/~oj14ozun/sp1/T12/02-sort.c,
 * für eine Implementierung einer qsort-artigen Funktion.
 */

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

/* ACHTUNG: Dieses Makro funktioniert nur für Arrays, wo sizeof(arr)
 * bestimmt wie viel Speicher ein Array insgesamt benutzt.
 * sizeof(ptr) sagt einem nur wie viel Speicher der Pointer selbst
 * braucht! */
#define LENGTH(arr) (sizeof (arr) / sizeof (*arr))

/* Diese Funktion gibt die uebliche Ordnung auf `int's an: `leftp' ist
 * kleiner als `rightp' wenn *leftp < *rightp, etc. */
int compar(const void *leftp, const void *rightp)
{
     int *left = (int*) leftp;
     int *right = (int*) rightp;
     
     /* qsort(3): "The comparison function must return an integer less
      * than, equal to, or greater than zero if the first argument is
      * considered to be respec‐ tively less than, equal to, or
      * greater than the second.  If two members compare as equal,
      * their order in the sorted array is undefined." */
     if (*left < *right) {
	  return -1;
     } else if (*left > *right) {
	  return 1;
     } else {
	  return 0;
     }

     /* Kurzform mit gleichem Verhalten:
      * return *((int*) leftp) - *((int*) right);
      * */
}

int main()
{
     /* Wir nehmen hier eine fixes Array von Zahlen an, rein zu
      * Beispielzwecken: */
     int nums[] = {
	  44, 7, 26, 3, 64, 75, 21, 51, 76, 40,
	  56, 32, 41, 53, 59, 74, 100, 88, 70,
	  16, 8, 82, 25, 90, 46, 79, 72, 1, 47,
	  35, 57, 5, 97, 11, 29, 24, 14, 38, 96,
	  54, 92, 28, 67, 65, 66, 61, 49, 93, 68,
	  81, 73, 43, 71, 20, 36, 12, 58, 99, 18,
	  13, 77, 17, 80, 34, 94, 27, 23, 45, 98,
	  87, 42, 30, 37, 62, 91, 31, 22, 69, 48,
	  84, 4, 2, 50, 9, 95, 83, 89, 55, 78, 15,
	  39, 86, 63, 6, 52, 60, 10, 33, 19, 85,
     };

     /* Hier der Trick: Qsort sortiert ein Array und muss wissen wie
      * viele Elemente es von jeweils von regelmäßiger Größe gibt.
      * Zeiger auf diese Elemente werden der Funktion `compar' zurück
      * gegeben.  Diese "call-back" funktion ruft unser eigenes
      * Programm auf!  Damit können wir das Verhalten manipulieren,
      * indem wir ein "Programm als Argument" übergeben. */
     qsort(nums, LENGTH(nums), sizeof *nums, compar);
     
     for (unsigned i = 0; i < LENGTH(nums); i++) {
	  printf("%d\n", nums[i]);
     }
     return 0;
}