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
%