計算機科学のブログ

C - 高度な関数 - 関数を最大限に活用する - 順序の設定, qsort関数

Head First C ―頭とからだで覚えるCの基本David Griffiths(著)、 Dawn Griffiths(著)、 中田 秀基(監修)、 木下 哲也(翻訳)、 O’Reilly Media)の 7章(高度な関数 - 関数を最大限に活用する)、p.321(エクササイズ)の解答を求めてみる。

Makefile

main: main.c
	cc main.c && ./a.out

コード

main.c

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

int compare_scores(const void *score_a, const void *score_b)
{
    int a = *(int *)score_a;
    int b = *(int *)score_b;
    return a - b;
}

int compare_scores_desc(const void *score_a, const void *score_b)
{
    int a = *(int *)score_a;
    int b = *(int *)score_b;
    return b - a;
}
typedef struct
{
    int width;
    int height;
} rectangle;
void print_rect(rectangle rect)
{
    printf("width: %i, height: %i, area: %i\n",
           rect.width, rect.height, rect.width * rect.height);
}
void print_rects(rectangle rects[], size_t len)
{
    for (size_t i = 0; i < len; i++)
    {
        print_rect(rects[i]);
    }
    puts("");
}
int compare_areas(const void *a, const void *b)
{
    rectangle *rect_a = (rectangle *)a;
    rectangle *rect_b = (rectangle *)b;
    int area_a = rect_a->width * rect_a->height;
    int area_b = rect_b->width * rect_b->height;
    return area_a - area_b;
}
void print_names(char *names[], size_t len)
{
    for (size_t i = 0; i < len; i++)
    {
        puts(names[i]);
    }
    puts("");
}
int compare_names(const void *a, const void *b)
{
    char *name_a = *(char **)a;
    char *name_b = *(char **)b;
    return strcmp(name_a, name_b);
}
int compare_areas_desc(const void *a, const void *b)
{
    rectangle *rect_a = (rectangle *)a;
    rectangle *rect_b = (rectangle *)b;
    int area_a = rect_a->width * rect_a->height;
    int area_b = rect_b->width * rect_b->height;
    return area_b - area_a;
}
int compare_names_desc(const void *a, const void *b)
{
    char *name_a = *(char **)a;
    char *name_b = *(char **)b;
    return strcmp(name_b, name_a);
}
void print_scores(int scores[], size_t len)
{
    for (size_t i = 0; i < len; i++)
    {
        printf("%i ", scores[i]);
    }
    puts("");
}
int main()
{
    int scores[] = {5, 1, 4, 2, 3};
    size_t len = 5;
    print_scores(scores, len);
    qsort(scores, len, sizeof(int), compare_scores);
    print_scores(scores, len);
    qsort(scores, len, sizeof(int), compare_scores_desc);
    print_scores(scores, len);
    rectangle rects[] = {{1, 2}, {9, 10}, {4, 3}, {8, 7}, {5, 6}};
    print_rects(rects, len);
    qsort(rects, len, sizeof(rectangle), compare_areas);
    print_rects(rects, len);
    qsort(rects, len, sizeof(rectangle), compare_areas_desc);
    print_rects(rects, len);
    char *names[] = {"A", "b", "B", "a", "C", "c"};
    print_names(names, 6);
    qsort(names, 6, sizeof(char *), compare_names);
    print_names(names, 6);
    qsort(names, 6, sizeof(char *), compare_names_desc);
    print_names(names, 6);
}

入出力結果(Terminal, Zsh)

% make
cc main.c && ./a.out
5 1 4 2 3 
1 2 3 4 5 
5 4 3 2 1 
width: 1, height: 2, area: 2
width: 9, height: 10, area: 90
width: 4, height: 3, area: 12
width: 8, height: 7, area: 56
width: 5, height: 6, area: 30

width: 1, height: 2, area: 2
width: 4, height: 3, area: 12
width: 5, height: 6, area: 30
width: 8, height: 7, area: 56
width: 9, height: 10, area: 90

width: 9, height: 10, area: 90
width: 8, height: 7, area: 56
width: 5, height: 6, area: 30
width: 4, height: 3, area: 12
width: 1, height: 2, area: 2

A
b
B
a
C
c

A
B
C
a
b
c

c
b
a
C
B
A

%