中間テストはペーパーテストが 12 点満点(順に 2, 2, 2, 2, 2, 2 点)、
オンラインテストが 8 点満点(4, 4 点)で採点する。
(ただし、最終的な成績の計算にはこの半分 — ペーパーテスト 6点満点、
オンラインテスト 4 点満点 — の割合で用いる。)
期末テストは、もっと難易度は高くなる。
今回はテストであるので、オンラインテストの解答に NG というメッセージがあっても、 再提出する必要はない。
ペーパーとオンラインを合算して、得点率が 7 割未満の者には、 追試験を実施する予定である。詳細は追って連絡する。
オンラインテストでセミコロンの付け忘れなど基本的な文法事項で何度もエラーを出しているようでは、 時間内に課題を仕上げることが非常に困難になる。 文法は“何となく”ではなく、確実に理解しておく必要がある。
以下のプログラムは動作はするがインデンテーションが滅茶苦茶でプログラム の構造を正しく反映していない。(そして、おそらく作成者の意図したように は動かない。)プログラムの構造を明確にするために if 文、if 〜 else 文、for 文は「インデンテーションの約束事」(別紙)の 5.「鉄の掟」に従って、 必ずブレースを使用するように(ただしプログラムの意味(実行結果)が変わらないように)書き換え、さらに 「インデンテーションの約束事」の 0. 〜 4. に従ってインデントしなおせ。
解答は、最初の #include <stdio.h> は省略せよ。
また、解答欄のスペースの都合で、(最後は別として)空行は入れずに記入せよ。
正解例は以下の通りである。
正しくインデントする以前の、ブレースの挿入の段階で間違っているのがほとんどである。 次のような誤りが多い。
あるいは、次の誤りも多い。
これだと、putchar('%'); は何度か実行されるが、
実際には一度も実行されない。
なかには、こんな誤答もあった。
else からはじまる文はない!!
上の 2 つの誤答例のようにプログラムの意味(実行結果)を変えてしまうようにブレースを入れてしまう誤答が とても多い。C 言語の文法の大事な部分が抜け落ちて、理解があやふやなまま、次へ進んでしまっている。構文図をしっかり理解しておくこと。
| if 文 | ||
| while 文 | ||
| for 文 |
上の構文図でわかるように、 あるいは教科書の p.44, p.46, p.48, pp.74–75, p.82, pp.94–95 に説明があるように、
if や while や for の対象となるのは
1 つの文である。
また pp. 60–61 に説明があるように
単一の文が要求される箇所に、複数の文(や宣言)を置かねばならないときは、 それらをまとめて(ブレースで囲んで)複合文(ブロック)として実現する。
| 複合文 |
だから、意味を変えないようにブレースを挿入するには、ブレース「{」〜「}」の
間に入るのは 1 つの文である。
(スペースや改行の位置は別にして、)ブレースは以下の位置に入る。
(else から始まる文はない、ということにも注意する。)
int main(void) {
int i = 1;
while (i++ <= 7) {
if (i % 3 == 1) {
putchar('#'); }
else if (i % 3 == 2) {
putchar('$'); }}
if (i % 2 == 0) {
putchar('%'); }
putchar('&');
return 0;
}
どこまでが 1 つの文かという基本的な文法がわかっていない人が多いと思われる。
は 1 つの文である(文のなかに文が含まれている)。一方、
は 2 つの文が並んでいるだけである。
開きブレース「{」と閉じブレース「}」の数が合わない、
という論外の誤答も意外に多くある。
開発チームの他の人や 3 ヵ月後の自分がソースを読んだときに、 勘違いが起きないよう、インデンテーションの約束事がある。 特に:
ブレース({ 〜 })の中の文は、外よりも 4
字分(首尾一貫した文字数)を字下げする。
(鉄の掟)if 文, if 〜 else 文 や for 文,
while 文, do 〜 while 文などでは、
選択されたり、繰り返したりされる文が一つだけの場合も、
ブレース({〜})に囲む。
は徹底する必要がある。
なお、このようなブレースを追加しても、 コンパイルされた結果である実行可能ファイルの効率が悪くなる心配はない。
インデンテーションがちゃんとできない人は、 肝心のプログラムの構造がわかっていない、勘でプログラムを作っている、 と判断される。教科書を読み返して、C 言語の文法を充分に理解しておくこと。
プログラミング言語の文法は、日本語や英語などの自然言語の文法に比べてはるかに単純である。 理解せずに勘でプログラムを書こうとするのは、時間の浪費で今後の進歩が望めない。
次のプログラムは一つの実数値を読み込んで、 それを 2.5 倍した値と、10 倍して小数点以下を切り捨てた値を表示するプログラムである。 たとえば、3.65 を入力すると、
整数を入力して下さい: 3.65↵
入力した値を 2.5 倍した値は 9.125000 です。
入力した値を 10 倍して切り捨てた値は 36 です。
と出力する。 空欄を埋めて、プログラムを完成せよ。
正解とコメントは以下のとおりである。 毎週使っているものだから、流石にもう覚えていないといけない。
| 番号 | 正解例 | コメント |
|---|---|---|
| (ⅰ) | %lf |
%d は int 型のための変換指定 |
| (ⅱ) | &x |
& を忘れている解答がときどきある |
| (ⅲ) | %f |
%lf は望ましくない |
| (ⅳ) | %d |
%f は double 型のための変換指定 |
以下の空欄を埋めて、 0 以上 140 未満の 7 の倍数をすべて昇順 (つまり、0, 7, 14, …, の順)に出力するプログラムを完成させよ。
正解例は i = 0; i < 140; i += 7などである。
140 未満ということは 140 は出力に含まれないので i = 0; i <= 140; i += 7
は間違いである。
i = 0; i < 140; i += 7; という間違いもたまにあったが、
セミコロンは 3 つの式を区切っているだけなので、最後にはつかない。
変数名が違うの(k = 0; k < 140; k += 7など)はもちろんダメである。
i >= 140など、第 2 式の不等号を逆にしてしまう間違いも多い。
この問題では i が増えていくので、これでは一度もループしないか無限にループし続けるかのどちらかになってしまう。
繰り返し文の条件は繰り返しが続くための条件であることを忘れてはいけない。
次のプログラムの出力を書け。
正解は、A C である。
B や C が出力されると考えた人は 3 章をよく復習しておくこと。
以下のプログラムは、整数の組のデータを
(i,j) という形式で出力する。
このプログラムの出力を書け。ただし、この問題の解答では、
空白は明示的に空白記号(␣)を、
改行は矢印(↵)を書くこと。
正解は以下の通りである。
(6,8)␣(6,6)␣(6,4)␣(6,2)␣↵ (4,2)␣(4,0)␣(4,8)␣↵ (2,6)␣(2,4)␣↵
「整数: 」と出力し、18 を受け取ったときに次のように出力するプログラムを作成する。
1?2!3?4!5? 6!7?8!9?0! 1?2!3?4!5? 6!7?8!
上の ⋮ の部分を埋めてプログラムを完成させよ。 使用できる記号列は以下から選び、記号Ⓐ~Ⓩの並びで答えよ。 なお(当然ながら)この問題ではインデンテーションは考慮しなくてよい。
一度だけ使用するもの:putchar('!');putchar('?');putchar('\n');printf("%d", i % 10);if (i % 2 == 0)if (i % 5 == 0)for (i = 1; i <= n; i++){}else正解は ⒼⓍⒹⒺⓍⒶⓎⓏⓍⒷⓎⒻⓍⒸⓎⓎ、すなわち
である。緑色のⓍとⓎ(ブレース)は必要だが、他のⓍとⓎはなくてもよい。
Ⅰ の問題ができていない人がこの問題もできていないという場合が多い。
下に示すように、正の整数 n を受け取って、
初項 -1、公差 3 の等差数列の第 1 項から第 n 項までを表示するプログラムを作成せよ。
ただし(値が) 4 の倍数(になる項)は数を ( と ) で囲め。
(n として負の数または 0 を受け取ったときは、何も表示しないか、改行のみ表示する。)
n? 7 -1 2 5 (8) 11 14 17実行例 2:
n? 21 -1 2 5 (8) 11 14 17 (20) 23 26 29 (32) 35 38 41 (44) 47 50 53 (56) 59
正解例は以下の通りである。
あるいは、コンマ演算子を使って次のように書いてもよい。
下に示すように、正の整数 n を受け取ってディ
スプレイ上に、最初の行に start と表示し、次の行に
横の長さ(列数)が n 文字の行を表示、1 行ごとに
1 文字分ずつ長さが短くなっていって、行の文字数が 1 文字まで減る左上直角三角形を表示する
プログラムを作成せよ。文字は、
1, 2, 3, 4, 5,
6, 7, 8, 9, 0,
1, …というように、
1 から始まって、9 の次は 0 に戻るようにせよ。ただし
3, 6, 9, … のように 3 の倍数列めには * が挿入されるようにせよ。
また最後に(空行を開けずに) end と表示せよ。
(n として負の数または 0 を受け取ったときは、start end のみを表示する。)
正の整数を入力してください: 5↵
start
12*34
56*7
89*
01
2
end
実行例 2:
正の整数を入力してください: 9↵
start
12*34*56*
78*90*12
34*56*7
89*01*
23*45
67*8
90*
12
3
end
実行例 3:
正の整数を入力してください: 13↵
start
12*34*56*78*9
01*23*45*67*
89*01*23*45
67*89*01*2
34*56*78*
90*12*34
56*78*9
01*23*
45*67
89*0
12*
34
5
end
実行例 4:
正の整数を入力してください: 0↵
start
end
正解例は以下の通りである。