単連結リストの整列 #107 たくさん打つのは面倒くさい
grade_t型はGRADE_A
のような定数を指す時にしか使わない。
用意した定数はすべてconst grade_t * const
型なので、
#include <stdio.h> #include "grade.h" int main(void) { grade_t *x = GRADE_A; grade_t *y = GRADE_A; printf("%d\n", grade_compare(x, y)); y = GRADE_B; printf("%d\n", grade_compare(x, y)); return 0; }
これはコンパイラに拒絶される。
次のように書かないといけない。
...snip const grade_t *x = GRADE_A; const grade_t *y = GRADE_A; ...snip
どうせ利用者側ではconst grade_t *
でしか使わないのにいちいちconst指定するのは面倒である。
そこで次のように変更してみる。
grade.h
#ifndef GRADE_H_INCLUDED #define GRADE_H_INCLUDED typedef const struct tag_grade *grade_t; extern grade_t const GRADE_A; extern grade_t const GRADE_B; extern grade_t const GRADE_C; extern grade_t const GRADE_D; extern grade_t const GRADE_F; /* compares g1 with g2 for order. returns a positive, zero, or a negative value as g1 > g2, g1 == g2, or g1 < g2. */ int grade_compare(grade_t g1, grade_t g2); #endif /* GRADE_H_INCLUDED */
grade.c
#include "grade.h" struct tag_grade { enum {GRADE_VAL_A = 5, GRADE_VAL_B = 4, GRADE_VAL_C = 3, GRADE_VAL_D = 2, GRADE_VAL_F = 1} grade; }; static struct tag_grade grades[] = {{GRADE_VAL_A}, {GRADE_VAL_B}, {GRADE_VAL_C}, {GRADE_VAL_D}, {GRADE_VAL_F}}; grade_t const GRADE_A = &grades[0]; grade_t const GRADE_B = &grades[1]; grade_t const GRADE_C = &grades[2]; grade_t const GRADE_D = &grades[3]; grade_t const GRADE_F = &grades[4]; int grade_compare(grade_t g1, grade_t g2) { if (g1->grade > g2->grade) return 1; else if (g1->grade == g2->grade) return 0; else return -1; }
これで最初に示したプログラムは、
...snip grade_t x = GRADE_A; grade_t y = GRADE_A; ...snip
のようにシンプルに書ける。