プログラムコードの前に,何をしたいかを書かないといけません.我々は英語で2種類の数を学んできたはずです.一つは,one, two, three, four, ...と数えていくもので,普通の数なのですが,「基数」と呼ばれます.もう一つの数は,first, second, third, fourth, ...と数えます.「序数」といいます.
いちいちスペルを書くのは面倒ですので,基数は1, 2, 3, 4, ...と表記するのが一般的です.それに対し除数については,1st, 2nd, 3rd, 4th, ...と書きます.ゲームなどの順位や,カレンダーの日付で見かけます.
そしてこの「st」「nd」「rd」「th」を,(序数の)接尾辞といい,基数(以下では「もとの数」と呼び,正の整数に限定します)に対し,次のルールで接尾辞が決まります.
- もとの数の10の位が1のとき,接尾辞は「th」
- もとの数の1の位が1のとき,接尾辞は「st」
- もとの数の1の位が2のとき,接尾辞は「nd」
- もとの数の1の位が3のとき,接尾辞は「rd」
- いずれでもないとき,接尾辞は「th」
1から数え上げていくと,「もとの数の10の位が1のとき」のもっとも小さい数は10で,11, 12, 13, 14, ..., 19と続きます.それぞれ,序数のスペルは,tenth, eleventh, twelfth, thirteenth, fourteenth, ..., nineteenthとなり,接尾辞はみな「th」です.なお20から23までは,twentieth,twenty-first, twenty-second, twenty-thirdとなり,これらは上記の「もとの数の1の位が1のとき」から始まる4つのルールにより,接尾辞が決まります.
準備が長くなりました.「もとの数」を,変数nに格納させておく(例えば,scanf関数で入力を獲得する)と,数および接尾辞の出力処理は以下のように書くことができます.
if ((n / 10) % 10 == 1) { printf("%dth\n", n); } else if (d == 1) { printf("%dst\n", n); } else if (d == 2) { printf("%dnd\n", n); } else if (d == 3) { printf("%drd\n", n); } else { printf("%dth\n", n); }
ここはelse ifを活用します.というのも5つ書いた,ライブラリ関数printfの呼び出しのうち,条件に合うよう,いずれか必ず1つを,実行する必要があるからです.
上記について,else ifを,単なるifにすると,どうなるでしょうか.次のコードです.
if ((n / 10) % 10 == 1) { printf("%dth\n", n); } if (d == 1) { printf("%dst\n", n); } if (d == 2) { printf("%dnd\n", n); } if (d == 3) { printf("%drd\n", n); } else { printf("%dth\n", n); }
これでは,「いずれか必ず1つを,実行する」というわけにいきません.例えばnが11のとき,最初の条件式の「(n / 10) % 10 == 1」*1が真となるので「11th」を出力し,その次の条件式の「d == 1」も真となるので,もう一度,「11st」を出力してしまいます*2.
「if〜(任意個の)else if〜else〜」は,条件分岐により,その中の処理を必ず1つだけ行うときに書く,と理解しておきましょう.