Sorting elements

Arrays and collections / Arrays

typedef struct {
    const char *letter;
    int number;
} Item;

//qsort takes a function that compares two elements: negative if a goes
//first, positive if b does, zero if they are equal
int ascending(const void *a, const void *b) {
    int x = *(const int *)a;
    int y = *(const int *)b;
    return (x > y) - (x < y); //x - y can overflow
}

int descending(const void *a, const void *b) {
    return ascending(b, a);
}

int byLetter(const void *a, const void *b) {
    return strcmp(((const Item *)a)->letter, ((const Item *)b)->letter);
}

void printArray(const char *name, const int arr[], size_t count) {
    printf("%s is {", name);
    for (size_t i = 0; i < count; i++) {
        if (i > 0) {
            printf(", ");
        }
        printf("%d", arr[i]);
    }
    printf("}\n");
}

int numbers[] = {11, 2, 5, 7, 3};
size_t count = sizeof numbers / sizeof numbers[0];

qsort(numbers, count, sizeof numbers[0], ascending);
//numbers is {2, 3, 5, 7, 11}
printArray("numbers", numbers, count);

qsort(numbers, count, sizeof numbers[0], descending);
//numbers is {11, 7, 5, 3, 2}
printArray("numbers", numbers, count);

//structs by a field
Item items[] = {{"B", 3}, {"A", 2}, {"C", 1}};
qsort(items, sizeof items / sizeof items[0], sizeof items[0], byLetter);
//items is {{"A", 2}, {"B", 3}, {"C", 1}}
printf("items is {{\"%s\", %d}, {\"%s\", %d}, {\"%s\", %d}}\n",
       items[0].letter, items[0].number, items[1].letter, items[1].number,
       items[2].letter, items[2].number);