これは簡単ですね。でもいくつか問題点があります。 これは、ある年しか使えません。月や日付の入力で おかしな数値を入力しても注意されません。 でもまあ、せっかく作ったのだから実行してみましょう。 月や日付の入力はユーザーの良識に任せることにします。#include <stdio.h> int main(void) { int date, mon, day; static mon_con[] = {2,5,5,1,3,6,1,4,0,2,5,0}; printf("月-->"); scanf("%d", &mon); printf("日-->"); scanf("%d", &date); day = (date + mon_con[mon - 1]) % 7; switch (day) { case 0: printf("日曜日です。\n"); break; case 1: printf("月曜日です\n"); break; case 2: printf("火曜日です\n"); break; case 3: printf("水曜日です\n"); break; case 4: printf("木曜日です\n"); break; case 5: printf("金曜日です\n"); break; case 6: printf("土曜日です\n"); break; default: printf("エラーです\n"); break; } return 0; }
うーん。1997年の5月31日は
土曜日なのか・・・(筆者の誕生日です)
実は、カレンダー(曜日)については大昔から ある公式があります。(Zellerの公式)
西暦y年m月d日の曜日は
(y+[y/4]-[y/100]+[y/400]+[2.6m+1.6]+d)mod7
で与えられます。なお1月と2月については、 前年の13月、14月としなくてはいけません。 うっかりこの決まりを忘れていると
[ ]記号は、Gauss記号といいます。
[x]とすると、これはxを越えない最大の整数を表します。
[4.2]=4
[0.95]=0
[-2.7]=-3
などとなります。
実は最近の数学ではGauss記号というのは 古いんだそうです。(筆者は詳しくは知らない)xを越えない 最大の整数は、「xの床(floor)」と言うそうです。 そして、Cでは、床を求める関数も用意されています。 その名もfloor関数です!
これは、わざわざ関数を使わなくてもマクロで 実現できると思いませんか? 暇な人は、マクロを考えてみてください。#include <math.h> double floor(double x);
modは剰余演算子(moddulus operator)と言われるもので Cでは%ですね。
では、上の公式を利用してもう少し進んだカレンダーを
作ってみましょう。
今回は、main関数にあまりごちゃごちゃ書かない 方針で行ってみましょう。まず、入力関数 を作ります。入力された、日付の曜日を計算する 関数も作りましょう。最後にこの曜日を表示する 関数を作りましょう。それぞれの関数プロトタイプは 次のようにします。
そうするとmain関数は次のようになるでしょう。void input_data(int *, int *, int *);//データ入力 int get_day(int, int, int); //曜日取得 void show_day_of_week(int); //曜日表示
あとは、各関数を書いていけばいいですね。 それと、「床」のマクロも作ってみましょう。int main(void) { int year, mon, date, day; //年、月、日、曜 input_data(&year, &mon, &date); if (mon <= 2) { mon += 12; year -= 1; } day = get_day(year, mon, date); show_day_of_week(day); return 0; }
ここで、ちょっと3項演算子「?」の説明をします。#define FL(x) ((int)(x) > (x) ? (int)(x) - 1 : (int)(x))
の形となります。まず式1が評価され真であれば式2が、偽であれば 式3が評価されそれが条件式の値となります。式1?式2:式3
次に各関数を見てみましょう。
yやmやdは、int型へのポインタであることに注意してください。 ここで、入力された年、月、日はmain関数でも有効です。void input_data(int *y, int *m, int *d) { printf("西暦="); scanf("%d", y); printf("月 ="); scanf("%d", m); printf("日 ="); scanf("%d", d); return; }
これは、公式通りに書いただけです。マクロも使っていますね。int get_day(int y, int m, int d) { int yobi; yobi = (y + FL(y / 4) - FL(y / 100) + FL(y / 400) + FL(2.6 * m + 1.6) + d) % 7; return yobi; }
return 公式;
でもいいのですが長くなるので yobiという変数を作って上のように書きました。 (特別な意味はありません。)
文字列の配列の扱いに注意してください。 漢字は1字でも2バイトなので文字列としなくてはいけません。 また、配列の初期化の方法も復習してください。 これらを、つなぎ合わせるとプログラムが出来上がりです。 もちろん#include <stdio.h>も忘れずに。void show_day_of_week(int d) { static char *yobi[] = {"日", "月", "火", "水", "木", "金", "土"}; printf("%s曜日です\n", yobi[d]); return; }
このプログラムで自分の生まれた曜日を調べてみましょう。
Update Dec/09/1996 By Y.Kumei