期末テストはペーパーテストが 32 点満点、
オンラインテストが 8 点満点で採点する。
今回はテストであるので、NG というメッセージがあっても、 再提出する必要はない。
以下のプログラムは動作はするがインデンテーションが滅茶苦茶でプログラムの構造を正しく反映していない。 (そして、おそらく作成者の意図したように は動かない。) プログラムの構造を明確にするために「プログラミング」のインデンテーションの約束事(別紙)に厳密に従って (特にⅴ番目のルールに注意)、必要に応じてブレースを挿入し、 インデントしなおせ。ただし、この問題では、ブレース内の字下げは3文字分とせよ。
もちろん、プログラムの意味(実行結果)が変わらないようにすること。
解答は、最初の #include <stdio.h> は省略せよ。また、 解答欄のスペースの都合で、空行は入れずに記入せよ。なお、 putchar は p-----r、 while は w---e のように省略してよい。
int main(void) {
int i, j;
for (i = 0; i < 9; i++)
if (i % 2 == 0)
for (j = 1; j < 9; j++)
putchar('&');
else
putchar('@');
putchar('*');
return 0;
}
正解は以下の通りである。
int main(void) {
int i, j;
for (i = 0; i < 9; i++) {
if (i % 2 == 0) {
for (j = 1; j < 9; j++) {
putchar('&');
}
} else {
putchar('@');
}
}
putchar('*');
return 0;
}
次のプログラムは、「整数を入力してください。」と出力してから一つの整数値を読み込んで、 その 1/3 の値を小数第 3 位まで出力し、 もし入力した整数が、-1 以下か 101 以上のときは続けて「想定外の入力です。」 と出力するプログラムである。空欄を埋めて、プログラムを完成させよ。
#includeint main(void) { int n; printf("整数を入力してください。"); scanf("%d", &n); printf("その 1/3 は %.3f です。\n", ); if ( ) { printf("想定外の入力です。\n"); } putchar('\n'); return 0; }
正解(例)とコメントは以下のとおりである。
| 番号 | 正解例 | コメント |
|---|---|---|
| (ⅰ) | n / 3.0 |
(double)n / 3 なども可 |
| (ⅱ) | n < 0 || 100 < n |
n <= -1 || 101 <= n なども可 |
以下のプログラムの空欄に、
double 型の引数 \(s\), \(p\) を受け取り、
\(\sqrt{s^2 - 4 p}\) を返す関数
double diff(double s, double p)
を定義せよ。(平方根を求めるライブラリー関数は sqrt である。)
#include <stdio.h> #include <math.h>int main(void) { double s = 7, p = 10; printf("2数の和が %.2f、積が %.2f のとき、差は %.2f です。\n", s, p, diff(s, p)); return 0; }
このプログラムは
2数の和が 7.00、積が 10.00 のとき、差は 3.00 です。
と出力する。
正解例は、以下の通りである。
double diff(double s, double p) {
return sqrt(s * s - 4 * p);
}
正解は以下の通りである。(問題文の掲載は省略する。)
(ⅰ). C (ⅱ). C (ⅲ). A (ⅳ). D (ⅴ). D (ⅵ). B (ⅶ). A (ⅷ). B (ⅸ). D (ⅹ). B
下に示すように、正の整数 n をキーボードから受け取って、初項 1, 公比 2 の等比数列の
第 1 項から第 n 項までを表示するプログラムを作成せよ。ただし、一の位が 2 になる数は
代わりにそれに 1 を足した数を表示すること。
(n として負の数または 0
を受け取ったときは、改行のみ表示するか、もしくは何も表示しなくてよい。)
正の整数を入力してください: 4↵
1 3 4 8
実行例 2:
正の整数を入力してください: 15↵
1 3 4 8 16 33 64 128 256 513 1024 2048 4096 8193 16384
実行例 3:
正の整数を入力してください: 0↵
実行例 4:
正の整数を入力してください: 1↵
1
正解例は以下の通りである。
#include <stdio.h>
int main(void) {
int i, a = 1, n;
printf("正の整数を入力してください: "); scanf("%d", &n);
for (i = 0; i < n; i++) {
if (a % 10 != 2) {
printf("%d ", a);
} else {
printf("%d ", a + 1);
}
a *= 2;
}
putchar('\n');
return 0;
}
下に示すように、正の整数 n をキーボードから受け取って、ディスプレイ上に、
一辺の長さが n の左下直角三角形を表示するプログラムを作成せよ。文字は
各行ごとに 1, 2, 3, 4, …, 8, 9, 0, 1, 2,… (つまり、列番を
10 で割った余り)を表示するが、全体で 5 の倍数個目(5 個目、10 個目、
15 個目、20 個目、…)には代わりに「#」を表示する。
(n として負の数または 0 を受け取ったときは何も表示しない、あるいは改行のみを表示する、
のいずれかで良い。)
正の整数を入力してください: 5↵
1
12
1#3
123#
1234#
実行例 2:
正の整数を入力してください: 13↵
1
12
1#3
123#
1234#
1234#6
123#567
1#3456#8
123#5678#
1234#6789#
1234#6789#1
123#5678#012
1#3456#8901#3
実行例 3:
正の整数を入力してください: 0↵
正解例は以下の通りである。
#include <stdio.h>
int main(void) {
int i, j, k = 1, n;
printf("正の整数を入力してください: "); scanf("%d", &n);
for (i = 1 ; i <= n; i++) {
for (j = 1; j <= i; j++) {
if (k % 5 == 0) {
putchar('#');
} else {
printf("%d", j % 10);
}
k++;
}
putchar('\n');
}
return 0;
}
int 型の引数 \(n\) を受け取り、
次のように定義される数列
\[\begin{eqnarray}
a_0 & = & n \\
a_k & = & \frac{2 a_{k - 1}}{3} & (k > 0\; かつ\; a_{k - 1} が\, 3\, の倍数のとき)\\
a_k & = & \frac{a_{k - 1}}{2} & (k > 0\; かつ\; a_{k - 1} が\, 3\, の倍数でない\, 2\, の倍数のとき)\\
a_k & = & a_{k - 1} - 1 & (k > 0\; かつ\; a_{k - 1} が\, 3 \,の倍数でも\, 2\, の倍数でもないとき)\\
\end{eqnarray}
\]
の、初めて \(a_k = 0\) となる正の
整数 \(k\) を返す関数 int
foo(int n) を定義せよ。\(n\) は 0 以上と仮定してよい。
例えば、\(n = 9\) のとき、\(\{ a_k \}\) は
\[a_0 = 9, a_1 = 6, a_2 = 4, a_3 = 2, a_4 = 1, a_5 = 0, a_6 = 0, a_7 = 0, \ldots\]
という数列なので、foo(9) は 5 である。
main 関数は、以下のコードを使用して、確認せよ。
int main(void) {
int i;
for (i = 1; i <= 30; i++) {
printf("foo(%d) = %d\n", i, foo(i));
}
return 0;
}
この main 関数の出力は次のようになる。
foo(1) = 1 foo(2) = 2 foo(3) = 3 foo(4) = 3 foo(5) = 4 foo(6) = 4 foo(7) = 5 foo(8) = 4 foo(9) = 5 foo(10) = 5 foo(11) = 6 foo(12) = 5 foo(13) = 6 foo(14) = 6 foo(15) = 6 foo(16) = 5 foo(17) = 6 foo(18) = 6 foo(19) = 7 foo(20) = 6 foo(21) = 7 foo(22) = 7 foo(23) = 8 foo(24) = 6 foo(25) = 7 foo(26) = 7 foo(27) = 7 foo(28) = 7 foo(29) = 8 foo(30) = 7
正解例は以下の通りである。
#include <stdio.h>
int foo(int n) {
int f = n, i = 0;
while (f != 0) {
if (f % 3 == 0) {
f = f * 2 / 3;
} else if (f % 2 == 0) {
f /= 2;
} else {
f--;
}
i++;
}
return i;
}
/* main は例 */
int main(void) {
int i;
for (i = 1; i <= 100; i++) {
printf("foo(%d) = %d\n", i, foo(i));
}
return 0;
}
int 型の配列 v と、
この配列の要素数を表す int 型の引数 no をこの順に受け取り、
v の隣り合う要素の差 v[i] - v[i - 1]の絶対値が 5
以上になる回数を返す関数
int bar(const int v[], int no)を定義せよ。例えば、
/* 差の絶対値が 5 以上の箇所を下線で示す。 */
int va[10] = {1, 6, 2, 4, 1, 5, 8, 2, 9, 7};
int vb[12] = {0, -6, -2, 6, -4, 2, 8, 4, 0, 2, 4, -2};
のとき、
bar(va, 10) は 3、
bar(vb, 12) は 6、
である。
正解例は以下の通りである。
#include <stdio.h>
int bar(const int a[], int n) {
int i, count = 0;
for (i = 1; i < n; i++) {
if (a[i] - a[i - 1] >= 5 || a[i] - a[i - 1] <= -5) {
count++;
}
}
return count;
}
int va[10] = {1, 6, 2, 4, 1, 5, 8, 2, 9, 7};
int vb[12] = {0, -6, -2, 6, -4, 2, 8, 4, 0, 2, 4, -2};
int main(void) {
int sa = sizeof(va) / sizeof(va[0]);
int sb = sizeof(vb) / sizeof(vb[0]);
printf("bar(va, %d) = %d\n", sa, bar(va, sa));
printf("bar(vb, %d) = %d\n", sb, bar(vb, sb));
return 0;
}