問題① 次のプログラムを実行したとき、B が出力されるのは、変数 value の値が以下のいずれのときですか? すべて選んでください。
#include <stdio.h>
int main(void)
{
int value;
if (value <= 10) {
puts("A");
}
else {
puts("B");
}
}
B が出力されるということは、value <= 10 が 0 になるときということです。value <= 10 は「変数value の値が 10 以下である」といっているので、その逆になる場合です。
「以下」の逆は「以上」ではなく、「より大きい」であることに注意してください。条件が逆であるということは、真だったものが偽になり、偽だったものが真にならなければならないからです。「以下」と「以上」はいずれも「同じ」であることを含んでいますから、「同じ」だったときの結果が逆になりません。
そのため、else の方にいくのは「変数value の値が 10 より大きいとき」です。選択肢の中でこれを満たしているのは、「15」だけです。
問題② switch文で書かれた次の分岐構造を、if文で書き換えてください。
#include <stdio.h>
// 整数の入力を受け取る
// 戻り値: 標準入力から整数の入力を受け取り、その値を返す。
int get_input_integer(void)
{
char s[40];
fgets(s, sizeof(s), stdin);
int value;
sscanf(s, "%d", &value);
return value;
}
int main(void)
{
puts("Please enter the integer.");
int value = get_input_integer();
switch (value) {
case 0:
puts("A");
break;
case 1:
puts("B");
break;
case 2:
puts("C");
break;
default:
puts("X");
break;
}
}
switch文は、if文で書き換えられます。caseラベルごとに else if を並べ、defaultラベルの代わりに単独の else を使えばいいです。
#include <stdio.h>
// 整数の入力を受け取る
// 戻り値: 標準入力から整数の入力を受け取り、その値を返す。
int get_input_integer(void)
{
char s[40];
fgets(s, sizeof(s), stdin);
int value;
sscanf(s, "%d", &value);
return value;
}
int main(void)
{
puts("Please enter the integer.");
int value = get_input_integer();
if (value == 0) {
puts("A");
}
else if (value == 1) {
puts("B");
}
else if (value == 2) {
puts("C");
}
else {
puts("X");
}
}実行結果:
Please enter the integer.
2 <-- 入力した整数
C
Please enter the integer.
3 <-- 入力した整数
X
ただし、このプログラムのように、caseラベルに書く値が連続的な場合は、switch文で書いた方が自然ですし、実行時の効率も高い可能性があります。
問題③ 2つの整数の入力を受け取り、大きい方の値を出力するプログラムを作成してください。if文を使う場合と、条件演算子を使う場合とで書いてみてください。
if文を使う場合は次のように書けます。
#include <stdio.h>
int main(void)
{
puts("Please enter the two integers.");
char s[40];
fgets(s, sizeof(s), stdin);
int a;
int b;
sscanf(s, "%d %d", &a, &b);
if (a > b) {
printf("%d\n", a);
}
else {
printf("%d\n", b);
}
}実行結果:
Please enter two integers.
20 10 <-- 入力した整数
20
a と b の値が同じだった場合は、どちらの値を出力しても同じことですから、if文の条件式📘は a >= b としても構いません。もちろん、a < b のように反対にして、0以外の場合と 0 の場合に実行する処理を入れ替えても同じ結果になります。
条件演算子を使う場合は、次のように書けます。
#include <stdio.h>
int main(void)
{
puts("Please enter the two integers.");
char s[40];
fgets(s, sizeof(s), stdin);
int a;
int b;
sscanf(s, "%d %d", &a, &b);
printf("%d\n", a > b ? a : b);
}実行結果:
Please enter two integers.
20 10 <-- 入力した整数
20
条件演算子の場合は、式であり、結果の値がつくられるため、printf関数の実引数に埋め込んでしまえます。
問題④ 入力されたスコアに応じて、以下のように * を出力したいとします。
* を出力して改行する* を出力して改行する* を出力して改行するそこで、次のようなプログラムを書きましたが、これは間違っています。その理由を答え、正しいプログラムを書いてください。
#include <stdio.h>
// 整数の入力を受け取る
// 戻り値: 標準入力から整数の入力を受け取り、その値を返す。
int get_input_integer(void)
{
char s[40];
fgets(s, sizeof(s), stdin);
int value;
sscanf(s, "%d", &value);
return value;
}
int main(void)
{
puts("Please enter the score.");
int score = get_input_integer();
if (score < 40) {
printf("\n");
}
else if (score >= 40) {
printf("*\n");
}
else if (score >= 70) {
printf("**\n");
}
else if (score == 100) {
printf("***\n");
}
}
たとえば 80 を入力されたとすると、** が出力されることを望んでいる訳ですが、このプログラムでは、* が出力されます。
こうなってしまうのは、上にある if から順番に調べていくからです。
1つ目の if文の条件式は score < 40 です。80 が入力されたのなら、これは 0(偽)になりますから、else に進みます。
そこには else if (score >= 40) があります。score には 80 が入っているので、この判定結果は 1(真)になります。したがって、*\n を出力して終了してしまいます。
これは条件式を並べる順番が悪いのです。以下のように並び替えると解決します。
#include <stdio.h>
// 整数の入力を受け取る
// 戻り値: 標準入力から整数の入力を受け取り、その値を返す。
int get_input_integer(void)
{
char s[40];
fgets(s, sizeof(s), stdin);
int value;
sscanf(s, "%d", &value);
return value;
}
int main(void)
{
puts("Please enter the score.");
int score = get_input_integer();
if (score == 100) {
printf("***\n");
}
else if (score >= 70) {
printf("**\n");
}
else if (score >= 40) {
printf("*\n");
}
else {
printf("\n");
}
}実行結果:
Please enter the score.
80 <-- 入力したスコア
**
「大きい・小さい」「以上・以下」の判定を使った条件で else if を並べるとき、その並び順は重要です。
問題⑤ 1 から 50 までの整数の中で、4 の倍数のものだけを出力するプログラムを作成してください。ただし、for文と if文を使うようにしてください。
実行結果はこうなります。
4
8
12
16
20
24
28
32
36
40
44
48
for文と if文を組み合わせて実現します。4 の倍数かどうかは、4 で割ったときに余りが出ないことで分かります。
#include <stdio.h>
int main(void)
{
for (int i = 1; i <= 50; ++i) {
if (i % 4 == 0) {
printf("%d\n", i);
}
}
}実行結果:
4
8
12
16
20
24
28
32
36
40
44
48
Programming Place Plus のトップページへ
| はてなブックマーク に保存 | Facebook でシェア | X で ポスト/フォロー |
| LINE で送る | noteで書く |
|
| 管理者情報 | プライバシーポリシー |