単連結リストの整列 #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

のようにシンプルに書ける。