中間テストはペーパーテストが 12 点満点(順に 2, 3, 2, 2, 3 点)、
オンラインテストが 8 点満点(4, 4 点)で採点する。
(ただし、最終的な成績の計算にはこの半分 — ペーパーテスト 6点満点、
オンラインテスト 4 点満点 — の割合で用いる。)
期末テストは、もっと難易度は高くなる。
今回はテストであるので、NG というメッセージがあっても、 再提出する必要はない。
ペーパーとオンラインを合算して、得点率が 6 割未満の者には、 追試験を実施する予定である。詳細は追って連絡する。
オンラインテストでセミコロンの付け忘れなど基本的な文法事項で何度もエラーを出しているようでは、 時間内に課題を仕上げることが非常に困難になる。 文法は“何となく”ではなく、確実に理解しておく必要がある。
以下であげる平均点などの統計値は暫定値であり、部分点の見直しなどの可能性はある。
以下のプログラムは動作はするがインデンテーションが滅茶苦茶でプログラム の構造を正しく反映していない。(そして、おそらく作成者の意図したように は動かない。)プログラムの構造を明確にするために「プログラミング」の インデンテーションの約束事(別紙)に厳密に従って(特に 5 番目のルー ルに注意)、必要に応じてブレースを挿入し、インデントしなおせ。ただし、 ブレース内の字下げは紙幅の制限のため 3 文字分とせよ。
もちろん、プログラムの意味(実行結果)が変わらないようにすること。 (つまり、作成者の(よくわからない)意図を忖度するのではなく、 コンパイラーが解釈する通りにインデントすること。)
解答は、最初の #include <stdio.h>
は省略せよ。
また、解答欄のスペースの都合で、(最後は別として)空行は入れずに記入せよ。
正解は以下の通りである。
次のような誤りが多い。ほぼ、半数が以下のどちらかの誤りを犯している。 この2つはどちらもプログラムの意味が変わってしまっている。
あるいは、
上の 2 つの誤答例のようにプログラムの意味(実行結果)を変えてしまうようにブレースを入れてしまう誤答が
とても多い。if
や for
の対象となるのは、1 つの文だから、
(スペースや改行の位置は別にして、)ブレースは以下の位置に入る。
int main(void) { int main(void) { int i, j; for (i = 0; i < 9; i++) { if (i % 2 == 0) { putchar('*'); } else if (i % 5 == 0) { putchar('@'); }} if (i % 3 == 0) { putchar('&'); } for (j = 0; j < 9; j++) { putchar('#'); } return 0; }
教科書の p.43, p.44, p.46, pp.58-59, p.72-73, p.80, pp.90-91 の図を確認しておくこと。
開発チームの他の人や 3 ヵ月後の自分がソースを読んだときに、 このような勘違いが起きないよう、インデンテーションの約束事がある。 特に:
ブレース({
〜 }
)の中は、外よりも 4(ただし、今回のテストでは 3)
字分(首尾一貫した文字数)を字下げする。
if
文, if
〜 else
文 や for
文,
while
文, do
〜 while
文などでは、
選択されたり、繰り返したりされる文が一つだけの場合も、
ブレース({
〜}
)に囲む。
は徹底する必要がある。
なお、このようなブレースを追加しても、 コンパイルされた結果である実行可能ファイルの効率が悪くなる心配はない。
正解したのは 26 名で、正解率は 29.5 % ( 26 / 88 ) だった。
インデンテーションがちゃんとできない人は、 肝心のプログラムの構造がわかっていない、勘でプログラムを作っている、 と判断せざるをえない。教科書を読み返して、C 言語の文法を充分に理解しておくこと。
プログラミング言語の文法は、日本語や英語などの自然言語の文法に比べてはるかに単純である。 理解せずに勘でプログラムを書こうとするのは、時間の浪費で、今後の進歩が望めない。
次のプログラムは一つの実数値を読み込んで、 それを 3 で割った値と、12 倍して切り捨てた値を表示するプログラムである。 たとえば、32.4 を入力すると、
実数を入力して下さい: 32.4↵
それを 3 で割った値は 10.800000 です。
それを 12 倍してから切り捨てた値は 388 です。
と出力する。 空欄を埋めて、プログラムを完成せよ。
正解(例)とコメントは以下のとおりである。
番号 | 正解例 | コメント |
---|---|---|
(ⅰ) | double |
|
(ⅱ) | %lf |
%d は int 型のための変換指定 |
(ⅲ) | &no |
|
(ⅳ) | %f |
%lf は誤り。 |
(ⅴ) | %d |
%.0f は小数第一位を四捨五入した double の値を表示するので、題意と違う。 |
(ⅵ) | (int) |
この問は正解率が低かった。 |
次のプログラムの出力を書け。
正解は、「A D
」である。
ほとんどできていたが、間違えた人は if〜else 文の意味を再確認しておくこと。
n % 5 == 0
という条件が成り立つので、else
部の
if (n % 15 == 0) { … }
は評価されない。つまり B
は出力されない。
以下の空欄を埋めて、 1 以上 210 以下の 7 の倍数をすべて降順 (つまり、210, 203, 196, …, 7 の順)に出力するプログラムを完成させよ。
正解例は、「k = 210; k > 0 ; k -= 7
」または「k = 210; k >= 1 ; k -= 7
」である。
「k = 210; n >= 7; k -= 7
」でも結果は変わらないが、初期値が 210
以外の値なら、結果が変わる可能性があるので、「k > 0
」か「k >= 1
」とするべきだろう。
「1 =< k
」や「k ≧ 1
」という解答があったが、
「=<
」や「≧
」という演算子は C 言語にはない。
「i = 210; i > 0; i -= 3
」など、変数名が違うのはもちろんダメである。
「k <= 0
」など、不等号の向きを逆にしてしまう間違いも多い。
これでは一度もループしないか、無限にループし続けるかのどちらかになってしまう。
「k -= 7
」のところを「k - 7
」という誤答もあった。これでは変数の値は変わらない。
「k = k - 7
」なら良い。
以下のプログラムは、整数の組のデータを
(i,j)
という形式で出力する。
このプログラムの出力を書け。ただし、この問題の解答では、
空白は明示的に空白記号(␣
)を、
改行は矢印(↵
)を書くこと。
正解は以下の通りである。
(1,1)␣↵ (2,2)␣(2,5)␣↵ (3,3)␣(3,6)␣(3,9)␣↵ (4,4)␣(4,7)␣(4,10)␣↵
繰り返しを用いて 1 から 60 までの整数 i
に対して、
60 を i
で割った商 (60 / i
) と
余り (60 % i
) を表示するプログラムを作成せよ。
下のように、各行は「60 = i * 商 + 余り
」 という形式で表示せよ、ただし、
余りが 0 のときは「 + 余り
」 の部分は表示せず、
「60 = i * 商
」という形式で表示せよ。
60 = 1 * 60 60 = 2 * 30 60 = 3 * 20 60 = 4 * 15 60 = 5 * 12 60 = 6 * 10 60 = 7 * 8 + 4 60 = 8 * 7 + 4 60 = 9 * 6 + 6 … 60 = 60 * 1
正解例は以下のとおりである。
正解率は 77 / 88(87.5 %)である。ただし、ここで正解とカウントしていても、 インデンテーションなどでの減点はありうる。
「n 回繰り返す」(「for (i = 1; i <= n; i++)
」
または、「for (i = 0; i < n; i++)
」)というのは繰返しの基本の形である。
これができていないのでは、とても正解に到達することはできない。
やはりインデンテーションが約束事にそってできていない解答が多い。 この問題の場合はインデンテーションの誤りは 10 〜 20 % の減点とする。
下に示すように、正の整数 n を受け取ってディスプレイ上に、
最初の行の長さ(文字数)が n, 1 行ごとに 2 文字分ずつ長さが短くなっていって、
縦の長さ(行数)が \(\dfrac{n}{2}\) (\(n\) が奇数のときは切り上げ)となる左上直角三角形を表示するプログラムを作成せよ。
文字は 01234560123456…
を繰り返して表示する。また最後に(途中に空行を開けずに) end
と表示せよ
(n として負の数または 0 を受け取ったときは、end
のみを表示する。)
正の整数を入力してください: 9↵
012345601
2345601
23456
012
3
end
実行例 2:
正の整数を入力してください: 12↵
012345601234
5601234560
12345601
234560
1234
56
end
実行例 3:
正の整数を入力してください: 0↵
end
正解例は以下のとおりである。
正解率は 33 / 88 (37.5 %)である。ただし、ここで正解とカウントしていても、インデンテーションなどでの減点はありうる。
n
の偶奇によって処理を分ける必要はない。シンプルな解答ができるように心がけないと、
問題が複雑になったときに手に負えなくなってしまう。