C言語課題の解説 -- カレンダープログラム --

この問題に対する模範解答として, ここに プログラムを示します.もちろんこのプログラムが完全という わけではありませんが,ほぼ問題のないプログラムだと思います. この課題には,C言語の基本についてわかっているかということ の他にいくつかのポイントがあります.それについて解説します.

  1. いくつかの関数にプログラムを分割しそれを組み合わせて見通しの良いプログラムを作れるか.

    プログラムをmainだけ,もしくはほぼ単一の関数で書くことは, プログラムのサイズがそれほど大きくない場合には, 難しくありませんが,それを続けて行くと大きなプログラムを 作ることができません.また,プログラムを再利用するという観点からも mainのみのプログラムでは利用できる範囲が限定されてしまいます.
  2. 配列がうまく使えるか.

    配列というデータ構造を用いることにより効率的にプログラミングができます. 逆にこのような構造を用いないと,非常に見通しの悪いプログラミングに なってしまいます.また,数の配列は問題ありませんが,文字列の配列 など,C言語の配列とポインタの関係はしっかりと理解している必要があります.
  3. プログラムの様式をうまく整えられるか

    プログラムは人間の読むものです.ある程度規模大きなプログラムは 何回も目で確かめて間違い探しをしなければなりません.そのとき, 様式が整えられているかどうかは,デバッグの効率に大きく依存します. 様式は一定のものであれば,何でも良いと言えますが,世の中で一般に 使われているいくつかの様式を用いることが安全です.また,1行が 非常識なほど長いというのは,やはり現実にはバグの原因となります. プログラミングの世界では1行を80文字に押さえるという常識があります (かつてDEC terminalの1行の横幅が80文字だったことに由来します). 現代では特に80文字に限定する必要はありませんが,それに揃えた方が 無難でしょう.また,C言語は演算子などの設計があまりしっかりと なされていないので,数式を詰めて書くと見づらくなります.C言語では 演算子(+, - , *, /など)の前後に1つ空白を入れることが常識と なっています.
  4. コンソールの出力系を理解しているか

    プログラムには必ず入力が必要ですし,計算した結果を出力しなければ 意味がありません.この場合,出力はprintf関数で行われることが一般的 であると思いますが,入力については工夫が必要です.この場合は codepadを用いていますので,scanfのような関数を使うことは非常に危険 であり,やらない方が良いと思います.また,そもそもscanfやgetsのような コンソールからの入力関数はネットワークの世界では古くからセキュリティ ホールになることが良く知られています.実用的に使われているプログラムで このような関数をそのまま利用しているものはほとんどないと考えられます. scanfなどが教科書で良く用いられるのは単にそれが初心者向けの教科書で あるからです.この問題の場合,scanfなどで情報を入力するのではなく, 適当な関数への入力として実現すれば十分であると思います.

また,プログラミングについてではありませんが,Zellerの公式を用いている 人が多く見られますが,問題の条件としては,この公式を与えておらず, 本来,これを使うのであれば,その正しさについても証明する必要が あると思います.このプログラムの場合,このような公式を用いる必要は 全くありません.素直に計算すればよいのではないでしょうか. プログラムの実行効率を問題にするのであれば,ひょっとすると 意味があるのかもしれませんが,ここではあまり意味がないと思います.


提出してくれた課題についてcodepadのそれぞれのページにコメントを書きました. また,様式については,提出されたプログラムを元に書き直したものを やはりcodepadに置きましたので,参考にしてください.

提出者


問い合わせ先: osami@meijo-u.ac.jp