3日目 5日目

4日目

目標

課題 4

カレンダプログラムを作ってみよう(3)

曜日って計算できる?

前回、西暦の年数から閏年かどうかを判定するルールを紹介し、それに基づいたプログラムを作成した。 閏年の判別方法が判るということは、年と月が判れば、どのような場合でもその月の日数が判ることになる。 ということは、年月日をすべて指定すると、ある基準日からの延べ日数が判るはずである。 さらに、曜日は7で割ったあまりで表現することができたのであるから、結局曜日も計算できることになる。

曜日を計算する方法は様々なものがあるが、ここでは、次の方法を使うことにしよう。 次の方法は西暦1600年以降の日付が与えられた場合、その日の曜日を求めるものである。

  1. 整数変数 y に年(西暦)を代入する
  2. 整数変数 m に月を代入する
  3. 整数変数 d に日を代入する
  4. y から 1600を引く
  5. 次のような条件に基づく処理を行う。
  6. d に(365.25*y)を加える
  7. d から (y/100) を引く
  8. d に (y/400) を加える
  9. さらに d に 30.6*m + 2.5を加える
  10. 得られた d を7で割った余りは、前回、決めたルールにしたがった曜日を表す数字である。

問題 4-1

上の手法をプログラムとして表現し、関数calendarの引数を 「年」と「月」に変更して mycal6.c として保存せよ。 できれば、「2007/11」の用にどの月のカレンダかを表示したり、 何曜日か判るようにしてみよう。

日本語を使う場合は、「ファイル(F)」→「エンコードの種類(D)」で、 あらかじめ「Unicode(UTF-8)」を選択しておく。

問題 4-2

曜日計算の 6から 9をまとめて行うと、正しい答えを出さない場合がある。 (たとえば 2007年11月 9日を試してみよ。) なぜだろうか?


解答例とその解説


新しい演算子

今日書いてきたプログラムでも良く出てきたのが、「ある変数に XX という操作を行った結果を、元の変数に代入する」という操作である。 (例: y = y - 1600; m = m - 3; 等) 今日の例題が特別なわけではなく、プログラムを書く場合に、このような操作は、よく必要となる。 そのため、C 言語ではこのような場合に利用できる特別な演算子「代入演算子」が存在する。 今までに出てきた算術演算子 「+-*/%」に対して、それぞれ次のような代入演算子がある

演算子 名称 使用例 意味
  *=   乗法代入演算子 a *= 5 a = a * 5
/= 商法代入演算子 a /= 6 a = a / 6
%= 剰余代入演算子 a %= 6 a = a % 6
+= 加法代入演算子 a += 400 a = a + 400
-= 減法代入演算子 y -= 1600 y = y - 1600

また、ある変数の値を1だけ増やす(減らす)という操作は、さらに良く行われるため これらにもインクリメント(デクリメント)演算子とよばれる特別な演算子が存在する。 変数 a の値を 1 増やす場合には a++ 等と利用する。 for文で

for ( i = 0; i < 3; ++i) {
...

等のように良く使われているのを目にすることができる。


宿題

2つの整数が与えられると、小さい方から大きい方までの、 すべての整数の和を表示するようなプログラムを作成しようとしている。

実行した場合、次のような表示になるように homework.c を完成させよ。

[user99@proge1]~/kadai04% ./homework
(1) + ... + (10) = 55
(100) + ... + (5) = 5040
[user99@proge1]~/kadai04%
/* homework.c */
#include <stdio.h>

int main()
{
	int a, b;

	a = 1;
	b = 10;

	printf("(%d) + ... + (%d) = %d\n", a, b, tashizan(a, b));

	a = 100;
	b = 5;

	printf("(%d) + ... + (%d) = %d\n", a, b, tashizan(a, b));

}

3日目 表紙 5日目

tacha@tack.fukui-med.ac.jp
$Id: 04.html,v 1.3 2007/11/08 18:06:19 tacha Exp $