中間テストはペーパーテストが 12 点満点(順に 2, 3, 2, 2, 3 点)、
オンラインテストが 8 点満点(4, 4 点)で採点する。
(ただし、最終的な成績の計算にはこの半分 — ペーパーテスト 6点満点、
オンラインテスト 4 点満点 — の割合で用いる。)
期末テストは、もっと難易度は高くなる。
今回はテストであるので、オンラインテストの解答に NG というメッセージがあっても、 再提出する必要はない。
ペーパーとオンラインを合算して、得点率が 7 割未満の者には、 追試験を実施する予定である。詳細は追って連絡する。
オンラインテストでセミコロンの付け忘れなど基本的な文法事項で何度もエラーを出しているようでは、 時間内に課題を仕上げることが非常に困難になる。 文法は“何となく”ではなく、確実に理解しておく必要がある。
以下のプログラムは動作はするがインデンテーションが滅茶苦茶でプログラム の構造を正しく反映していない。(そして、おそらく作成者の意図したように は動かない。)プログラムの構造を明確にするために if 文、if 〜 else 文、for 文、while 文は「インデンテーションの約束事」(別紙)の 5.「鉄の掟」に従って、 必ずブレースを使用するように(ただしプログラムの意味(実行結果)が変わらないように)書き換え、さらに 「インデンテーションの約束事」の 0. 〜 4. に従ってインデントしなおせ。
解答は、最初の #include <stdio.h>
は省略せよ。
また、解答欄のスペースの都合で、(最後は別として)空行は入れずに記入せよ。
正解例は以下の通りである。
正しくインデントする以前の、ブレースの挿入の段階で間違っているのがほとんどである。 次のような誤りが多い。
あるいは、次の誤りも多い。
これだと、putchar('\n');
は i % 3 != 0
のときしか実行されないが、
実際には常に実行される。
上の 2 つの誤答例のようにプログラムの意味(実行結果)を変えてしまうようにブレースを入れてしまう誤答が とても多い。C 言語の文法の大事な部分が抜け落ちて、理解があやふやなまま次へ進めてしまっていると言わざるを得ない。
教科書の p.44, p.46, p.48, pp.74–75, p.82, pp.94–95 に説明があるように、
if
や while
や for
の対象となるのは
1 つの文である。
また pp. 60–61 に説明があるように
単一の文が要求される箇所に、複数の文(や宣言)を置かねばならないときは、
それらをまとめて(ブレースで囲んで)複合文(ブロック)として実現する。
だから、意味を変えないようにブレースを挿入するには、ブレース「{
」〜「}
」の
間に入るのは1 つの文である。
(スペースや改行の位置は別にして、)ブレースは以下の位置に入る。
int main(void) { int i; for (i = 1; i <= 6; i++) { if (i % 2 == 0){ putchar('#');}} if (i % 3 == 0){ putchar('$');} else { putchar('%');} putchar('\n'); return 0; }
開きブレース「{
」と閉じブレース「}
」の数が合わない、という論外の誤答も意外に多く(10 人超)ある。
開発チームの他の人や 3 ヵ月後の自分がソースを読んだときに、 このような勘違いが起きないよう、インデンテーションの約束事がある。 特に:
ブレース({
〜 }
)の中の文は、外よりも 4
字分(首尾一貫した文字数)を字下げする。
(鉄の掟)if
文, if
〜 else
文 や for
文,
while
文, do
〜 while
文などでは、
選択されたり、繰り返したりされる文が一つだけの場合も、
ブレース({
〜}
)に囲む。
は徹底する必要がある。
なお、このようなブレースを追加しても、 コンパイルされた結果である実行可能ファイルの効率が悪くなる心配はない。
次のプログラムは一つの実数値を読み込んで、 それを 3.14 倍した値と、100 倍した値を切り捨てて整数とした値を表示するプログラムである。 たとえば、4.256 を入力すると、
実数を入力して下さい: 4.256↵
3.14 倍した値は 13.363840 です。
100 倍して切り捨てた値は 425 です。
と出力する。 空欄を埋めて、プログラムを完成せよ。
正解(例)とコメントは以下のとおりである。
番号 | 正解例 | コメント |
---|---|---|
(ⅰ) | %lf |
%d は double 型のための変換指定 |
(ⅱ) | &d |
& を忘れている解答がときどきある |
(ⅲ) | %f |
%lf は望ましくない |
(ⅳ) | 3.14 * d |
|
(ⅴ) | %d |
%f は double 型のための変換指定 |
(ⅵ) | (int)(d * 100) |
int(d * 100) という書き方は C にはない。(int)d * 100 だと切り捨ててから 100 倍になる
|
(ⅴ), (ⅵ) は %.0f
と d * 100
でよいと思うかもしれないが、
これは切り捨てにはならず、偶数丸めになる(ことが多い)。(C 言語の仕様では明確に定まっていない。)
次のプログラムの出力を書け。
正解は、「B D
」である。
「B C D
」という間違いも 10 人超あった。
これを間違える人は、やはり、大事な部分をおざなりにしたままである。
教科書 § 3-1 をよく読んでおくこと。
以下の空欄を埋めて、 96 以上 200 未満の 4 の倍数をすべて昇順 (つまり、96, 100, 104, …, の順)に出力するプログラムを完成させよ。
正解例は、「i = 96; i < 200; i += 4
」などである。
未満と以下を取り違えている人が若干いたが、 このような用語は正確に使い分けを理解する必要がある。この問題は 200 未満なので、200 は含まれない。
変数名が違うの(「k = 96; k < 200; k += 4
」など)はもちろんダメである。
以下のプログラムは、整数の組のデータを
(i,j)
という形式で出力する。
このプログラムの出力を書け。ただし、この問題の解答では、
空白は明示的に空白記号(␣
)を、
改行は矢印(↵
)を書くこと。
正解は以下の通りである。
(0,1)␣↵ (2,5)␣(2,2)␣↵ (4,9)␣(4,6)␣(4,3)␣(4,0)␣↵
右
(0,1)␣(0,-2)␣↵ (2,5)␣(2,2)␣(2,-1)␣↵ (4,9)␣(4,6)␣(4,3)␣(4,0)␣(4,-3)␣↵
あるいは、下
(0,1)␣↵
(2,5)␣(2,2)␣↵
(4,9)␣(4,6)␣(4,3)␣(4,0)␣↵
(6,13)␣(6,10)␣(6,7)␣(6,4)␣(6,1)␣↵
に 1 つ多いという誤答が多い。これを間違える人は for 文の繰り返しの条件を正確に理解していない。
繰り返しを用いて 1 から 60 までの整数 i
に対して、
i を 7 で割った余りを表示するプログラムを作成せよ。
ただし、余りが 0 のときは空行のみ表示せよ。
1 を 7 で割った余りは 1 です。 2 を 7 で割った余りは 2 です。 3 を 7 で割った余りは 3 です。 4 を 7 で割った余りは 4 です。 5 を 7 で割った余りは 5 です。 6 を 7 で割った余りは 6 です。 8 を 7 で割った余りは 1 です。 9 を 7 で割った余りは 2 です。 10 を 7 で割った余りは 3 です。 11 を 7 で割った余りは 4 です。 12 を 7 で割った余りは 5 です。 13 を 7 で割った余りは 6 です。 15 を 7 で割った余りは 1 です。 ⋮ 60 を 7 で割った余りは 4 です。
正解例は以下のとおりである。
あるいは
「n 回繰り返す」(「for (i = 1; i <= n; i++)
」
または、「for (i = 0; i < n; i++)
」)というのは繰返しの基本の形である。
これができていないのでは、とても正解に到達することはできない。
繰り返しの範囲(1 から 60 まで)が正確でない、という誤答も意外に多い。
下に示すように、正の整数 n を受け取ってディスプレイ上に、
最初の横の長さ(列数)が 1 で 1 行ごとに 2 文字分ずつ長さが長くなっていって、最大で n まで増える
(つまり n が偶数のときは n - 1 まで増える)左下直角三角形を表示するプログラムを作成せよ。
数字は、0 から始まって、0, 1, 2, 3, 4, 5, 6, 7, 8, 9, @, 0, 1, … というように、9 と 0 のあいだに @
をはさむようにせよ。
また最後に(空行を開けずに) end
と表示せよ。
(n として負の数または 0 を受け取ったときは、end
のみを表示する。)
正の整数を入力してください: 5↵
0
123
45678
end
実行例 2:
正の整数を入力してください: 9↵
0
123
45678
9@01234
56789@012
end
実行例 3:
正の整数を入力してください: 12↵
0
123
45678
9@01234
56789@012
3456789@012
end
実行例 4:
正の整数を入力してください: 0↵
end
正解例は以下のとおりである。
あるいは
下のようなやり方をしている解答が多かった。
このやりかたは、9
が行末に現れると破綻する。
問題を少し変えて、数字を0 ではなく 1 から始めるようにすると、k
の初期値を 1 にするだけでは対応できなくなる。
正の整数を入力してください: 7↵ 1 234 56789@ 0123456 end
本当は、下のような実行例にならなければいけない。
正の整数を入力してください: 7↵
1
234
56789
@012345
end
だから、上の解答が正解であるためには、本当は、元の条件で9
が行末に現れないことを証明できなければならない。