授業/C言語基礎/数当てゲーム
をテンプレートにして作成
開始行:
これまでに勉強したことを使って、次のような簡単な数当てゲ...
コンピューターがある数を一つ決め、プレイヤーがその数を...
コンピューターは、プレイヤーが答えた数が正解よりも大き...
*実行結果をイメージする [#c224395d]
プログラムを作るときは、まず、プログラムの実行結果をイメ...
このプログラムを実行すると、まずはじめに、コンピューター...
とりあえず、正解の数を33として話を進めます。
次に、コンピューターが、プレイヤーに数の入力を要求します。
入力を要求するメッセージは次のような感じにしましょう。
整数を入力してください:
ここで、プレイヤーが99と入力したとすると、99は正解の33よ...
整数を入力してください:
99
大きすぎます
整数を入力してください:
今度は、プレイヤーが11と入力したとすると、11は正解の33よ...
整数を入力してください:
99
大きすぎます
整数を入力してください:
11
小さすぎます
整数を入力してください:
プレイヤーが正解を入力すると、「正解」というメッセージを...
整数を入力してください:
99
大きすぎます
整数を入力してください:
11
小さすぎます
整数を入力してください:
33
正解!
このように、実行結果をイメージすることで、プログラムの中...
*フローチャートを作る [#e134d110]
次に、イメージした実行結果になるように、プログラムのフロ...
このプログラムは、二つの部分に分けることができます。
+コンピューターがある数(正解)を一つ決める
+プレイヤーが答える
最初の、コンピューターがある数(正解)を一つ決めるところ...
乱数の使い方がわからない場合は、自分で正解の値を決めても...
その次の、プレイヤーが答えるところは、これまでに勉強した...
この部分の中心は、ユーザーが答えて、それが正解よりも大き...
+scanf関数でキーボードから入力する
+if文で入力された数と正解を比べる
--入力された数が正解よりも大きいならば、「大きすぎる」と...
--入力された数が正解よりも小さいならば、「小さすぎる」と...
これを、正解が入力されるまで繰り返します。
この流れを、そのままフローチャートにすると、次のようにな...
#ref(./number1.png,50%)
ところが、これだと、繰り返しの部分がC言語の繰り返し処理の...
そこで、繰り返しの文をC言語の繰り返し処理のフローチャート...
#ref(./number2.png,50%);
*プログラムを作る [#k81d93b9]
フローチャートができたら、プログラムを作ります。
乱数を使って正解の数を決める部分だけを作ると、次のように...
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r;
srand((unsigned int) time(NULL)); // 乱数のシード
r = rand() % 100 + 1;
return 0;
}
}}
ここでは、正解の数は、1から100までの整数としています。
rand関数、srand関数、time関数の使い方については、[[計算ゲ...
(ここで、一度コンパイルして、エラーがないか確認します。)
次に、その後の繰り返し処理を形だけ作ります。
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r;
srand((unsigned int) time(NULL)); // 乱数のシード
r = rand() % 100 + 1;
while (1) {
}
printf("正解!\n");
return 0;
}
}}
while文の繰り返し条件が1になっているのは、コンパイル時に...
条件は後で作り直します。
忘れないように注意しましょう。
(ここで、もう一度コンパイルして、エラーがないか確認しま...
while文の形ができたら、先に、繰り返し処理の中を考えましょ...
繰り返し処理の中だけを考えると、次の3つの処理が必要になり...
+プレイヤーに入力を要求するprintf関数
+プレイヤーの答をキーボードから入力するscanf関数
+大きいか小さいかを判定するif文
したがって、繰り返し処理の中は、次のようになります。
#geshi(c){{
printf("1から100までの整数を入力してください:\n");
scanf("%d", &a);
if (a > r) {
printf("大きすぎます\n");
} else if (a < r) {
printf("小さすぎます\n");
}
}}
ここで、a はプレイヤーが入力した数を記憶しておくための変...
そこで、これをwhile文の波括弧 { } の中にいれて、新しく登...
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r, a;
srand((unsigned int) time(NULL)); // 乱数のシード
r = rand() % 100 + 1;
while (1) {
printf("1から100までの整数を入力してください:\n");
scanf("%d", &a);
if (a > r) {
printf("大きすぎます\n");
} else if (a < r) {
printf("小さすぎます\n");
}
}
printf("正解!\n");
return 0;
}
}}
(ここで、もう一度コンパイルして、エラーがないか確認しま...
正解でない間、繰り返すので、繰り返し条件は「a と r が等し...
また、最初は、繰り返し条件を必ず満たすようにしなければな...
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r, a;
srand((unsigned int) time(NULL)); // 乱数のシード
r = rand() % 100 + 1;
a = -1;
while (a != r) {
printf("1から100までの整数を入力してください:\n");
scanf("%d", &a);
if (a > r) {
printf("大きすぎます\n");
} else if (a < r) {
printf("小さすぎます\n");
}
}
printf("正解!\n");
return 0;
}
}}
これで完成です(プログラム1)。
プログラムができたら、コンパイルして、エラーを直します。
途中で何度かコンパイルしてそのたびにエラーを直しておくと...
**演習1 [#sd1ca6c5]
プログラム1を作成し、実行結果を確認せよ。
*プログラムをテストする(おまけ) [#s201611e]
プログラムが完成したら、何度か実行して設計図(フローチャ...
これを''テスト''といいます。
テストでは、まず、プログラムをモジュールに分割し、モジュ...
これを''単体テスト''といいます。
単体テストのやり方はいくつかありますが、その中に、''ブラ...
これはこの後で説明します。
すべてのモジュールのテストが終わったら、モジュールを組み...
これを''結合テスト''といいます。
このプログラムは、次の二つのモジュールに分割できます。
+コンピューターが乱数で問題を生成する
+プレイヤーが答えて判定する
そこで、まず、コンピューターがきちんと問題を生成できてい...
乱数を生成した後にprintf関数を置いて生成された数を表示し...
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r, a;
int i; // テスト用
srand((unsigned int) time(NULL)); // 乱数のシード
// テスト用
for (i = 1; i <= 1000; i++) {
r = rand() % 100 + 1;
printf("# r = %d\n", r);
if (r < 1 || r > 100) { exit(1); }
}
/*
r = rand() % 100 + 1;
*/
a = -1;
while (a != r) {
printf("1から100までの整数を入力してください:\n");
scanf("%d", &a);
if (a > r) {
printf("大きすぎます\n");
} else if (a < r) {
printf("小さすぎます\n");
}
}
printf("正解!\n");
return 0;
}
}}
if文の中の''exit関数''は、プログラムの実行を終了する関数...
テスト用のコードが間違えていると、正しくテストができませ...
また、テストが終わったらすぐに元に戻せるように、元のプロ...
**演習2 [#s573810c]
プログラム1をプログラム2に変更し、テストを実行せよ。
**ブラック・ボックス・テスト [#lbb3ab44]
コンピューターが問題を正しく作成できることを確認したら、...
コンピュータが問題を正しく生成できることは確認済みなので...
ここでは、実行結果をイメージするときに使った33とします(...
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r, a;
srand((unsigned int) time(NULL)); // 乱数のシード
r = rand() % 100 + 1;
r = 33; // テスト用
a = -1;
while (a != r) {
printf("1から100までの整数を入力してください:\n");
scanf("%d", &a);
if (a > r) {
printf("大きすぎます\n");
} else if (a < r) {
printf("小さすぎます\n");
}
}
printf("正解!\n");
return 0;
}
}}
''ブラック・ボックス・テスト''は、プログラムの中身をわか...
ブラック・ボックス・テスト用のテスト・ケースを作成する方...
''同値分割法''では、入力データを仕様に基づいてグループに...
ここでは、正解よりも大きい数、正解よりも小さい数、正解と...
そこで、正解よりも大きい数の代表として99、正解よりも小さ...
テスト・ケースを選んだら、テスト・ケースを順番に入力し、...
#geshi(sh){{
luna% a.out
整数を入力してください:
99
大きすぎます
整数を入力してください:
11
小さすぎます
整数を入力してください:
33
正解!
}}
''境界値分析''では、境界値を用いてテストを行います。
ここでは、正解よりも小さい数と正解の境界値である32と33、...
テスト・ケースを選んだら、テスト・ケースを順番に入力し、...
#geshi(sh){{
luna% a.out
整数を入力してください:
32
小さすぎます
整数を入力してください:
33
正解!
luna% a.out
整数を入力してください:
34
大きすぎます
整数を入力してください:
}}
**演習3 [#zd2969f9]
ブラック・ボックス・テストの同値分割法と境界値分析を用い...
**ホワイト・ボックス・テスト [#ob534ab6]
''ホワイト・ボックス・テスト''は、プログラムの制御構造に...
ホワイト・ボックス・テスト用のテスト・ケースを作成する方...
''ステートメント・カバレッジ''では、すべての命令文(ステ...
プレイヤーが答えて判定する部分には、1つの代入、4つのprint...
そこで、この6つのステートメントをできる限り多くカバーする...
最初の代入、printf関数、scanf関数は、入力データに関係なく...
2番目の「大きすぎる」と出力するprintf関数は、入力データが...
ここでは、99とします。
3番目の「小さすぎる」と出力するprintf関数は、入力データが...
ここでは、11とします。
最後の「正解」と出力するprintf関数は、入力データが正解に...
ここでは、33です。
テスト・ケースを選んだら、テスト・ケースを順番に入力し、...
#geshi(sh){{
luna% a.out
整数を入力してください:
99
大きすぎます
整数を入力してください:
11
小さすぎます
整数を入力してください:
33
正解!
}}
すべての命令文を実行できたので、このテストのステートメン...
''ブランチ・カバレッジ''(''分岐網羅'')では、フローチャ...
フローチャート2に基づいて、次のようなケースを用意すると、...
+入力された数が正解よりも大きい場合
+入力された数が正解よりも大きくない、かつ、正解よりも小さ...
+入力された数が正解よりも大きくない、かつ、正解よりも小さ...
すると、テスト・ケースは 99, 11, 33 とすればいいことにな...
つまり、このテストは、ステートメント・カバレッジが100%で...
**演習4 [#bbd75a56]
ホワイト・ボックス・テストのステートメント・カバレッジと...
----
*まとめ [#wd06b188]
プログラム作成は、設計、コーディング、テストの順に行いま...
まず、出力結果のイメージを作成し、プログラムの流れをフロ...
フローチャートができたら、フローチャートに基づいてプログ...
プログラムができたら、正しく動くことを確認します(テスト...
終了行:
これまでに勉強したことを使って、次のような簡単な数当てゲ...
コンピューターがある数を一つ決め、プレイヤーがその数を...
コンピューターは、プレイヤーが答えた数が正解よりも大き...
*実行結果をイメージする [#c224395d]
プログラムを作るときは、まず、プログラムの実行結果をイメ...
このプログラムを実行すると、まずはじめに、コンピューター...
とりあえず、正解の数を33として話を進めます。
次に、コンピューターが、プレイヤーに数の入力を要求します。
入力を要求するメッセージは次のような感じにしましょう。
整数を入力してください:
ここで、プレイヤーが99と入力したとすると、99は正解の33よ...
整数を入力してください:
99
大きすぎます
整数を入力してください:
今度は、プレイヤーが11と入力したとすると、11は正解の33よ...
整数を入力してください:
99
大きすぎます
整数を入力してください:
11
小さすぎます
整数を入力してください:
プレイヤーが正解を入力すると、「正解」というメッセージを...
整数を入力してください:
99
大きすぎます
整数を入力してください:
11
小さすぎます
整数を入力してください:
33
正解!
このように、実行結果をイメージすることで、プログラムの中...
*フローチャートを作る [#e134d110]
次に、イメージした実行結果になるように、プログラムのフロ...
このプログラムは、二つの部分に分けることができます。
+コンピューターがある数(正解)を一つ決める
+プレイヤーが答える
最初の、コンピューターがある数(正解)を一つ決めるところ...
乱数の使い方がわからない場合は、自分で正解の値を決めても...
その次の、プレイヤーが答えるところは、これまでに勉強した...
この部分の中心は、ユーザーが答えて、それが正解よりも大き...
+scanf関数でキーボードから入力する
+if文で入力された数と正解を比べる
--入力された数が正解よりも大きいならば、「大きすぎる」と...
--入力された数が正解よりも小さいならば、「小さすぎる」と...
これを、正解が入力されるまで繰り返します。
この流れを、そのままフローチャートにすると、次のようにな...
#ref(./number1.png,50%)
ところが、これだと、繰り返しの部分がC言語の繰り返し処理の...
そこで、繰り返しの文をC言語の繰り返し処理のフローチャート...
#ref(./number2.png,50%);
*プログラムを作る [#k81d93b9]
フローチャートができたら、プログラムを作ります。
乱数を使って正解の数を決める部分だけを作ると、次のように...
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r;
srand((unsigned int) time(NULL)); // 乱数のシード
r = rand() % 100 + 1;
return 0;
}
}}
ここでは、正解の数は、1から100までの整数としています。
rand関数、srand関数、time関数の使い方については、[[計算ゲ...
(ここで、一度コンパイルして、エラーがないか確認します。)
次に、その後の繰り返し処理を形だけ作ります。
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r;
srand((unsigned int) time(NULL)); // 乱数のシード
r = rand() % 100 + 1;
while (1) {
}
printf("正解!\n");
return 0;
}
}}
while文の繰り返し条件が1になっているのは、コンパイル時に...
条件は後で作り直します。
忘れないように注意しましょう。
(ここで、もう一度コンパイルして、エラーがないか確認しま...
while文の形ができたら、先に、繰り返し処理の中を考えましょ...
繰り返し処理の中だけを考えると、次の3つの処理が必要になり...
+プレイヤーに入力を要求するprintf関数
+プレイヤーの答をキーボードから入力するscanf関数
+大きいか小さいかを判定するif文
したがって、繰り返し処理の中は、次のようになります。
#geshi(c){{
printf("1から100までの整数を入力してください:\n");
scanf("%d", &a);
if (a > r) {
printf("大きすぎます\n");
} else if (a < r) {
printf("小さすぎます\n");
}
}}
ここで、a はプレイヤーが入力した数を記憶しておくための変...
そこで、これをwhile文の波括弧 { } の中にいれて、新しく登...
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r, a;
srand((unsigned int) time(NULL)); // 乱数のシード
r = rand() % 100 + 1;
while (1) {
printf("1から100までの整数を入力してください:\n");
scanf("%d", &a);
if (a > r) {
printf("大きすぎます\n");
} else if (a < r) {
printf("小さすぎます\n");
}
}
printf("正解!\n");
return 0;
}
}}
(ここで、もう一度コンパイルして、エラーがないか確認しま...
正解でない間、繰り返すので、繰り返し条件は「a と r が等し...
また、最初は、繰り返し条件を必ず満たすようにしなければな...
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r, a;
srand((unsigned int) time(NULL)); // 乱数のシード
r = rand() % 100 + 1;
a = -1;
while (a != r) {
printf("1から100までの整数を入力してください:\n");
scanf("%d", &a);
if (a > r) {
printf("大きすぎます\n");
} else if (a < r) {
printf("小さすぎます\n");
}
}
printf("正解!\n");
return 0;
}
}}
これで完成です(プログラム1)。
プログラムができたら、コンパイルして、エラーを直します。
途中で何度かコンパイルしてそのたびにエラーを直しておくと...
**演習1 [#sd1ca6c5]
プログラム1を作成し、実行結果を確認せよ。
*プログラムをテストする(おまけ) [#s201611e]
プログラムが完成したら、何度か実行して設計図(フローチャ...
これを''テスト''といいます。
テストでは、まず、プログラムをモジュールに分割し、モジュ...
これを''単体テスト''といいます。
単体テストのやり方はいくつかありますが、その中に、''ブラ...
これはこの後で説明します。
すべてのモジュールのテストが終わったら、モジュールを組み...
これを''結合テスト''といいます。
このプログラムは、次の二つのモジュールに分割できます。
+コンピューターが乱数で問題を生成する
+プレイヤーが答えて判定する
そこで、まず、コンピューターがきちんと問題を生成できてい...
乱数を生成した後にprintf関数を置いて生成された数を表示し...
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r, a;
int i; // テスト用
srand((unsigned int) time(NULL)); // 乱数のシード
// テスト用
for (i = 1; i <= 1000; i++) {
r = rand() % 100 + 1;
printf("# r = %d\n", r);
if (r < 1 || r > 100) { exit(1); }
}
/*
r = rand() % 100 + 1;
*/
a = -1;
while (a != r) {
printf("1から100までの整数を入力してください:\n");
scanf("%d", &a);
if (a > r) {
printf("大きすぎます\n");
} else if (a < r) {
printf("小さすぎます\n");
}
}
printf("正解!\n");
return 0;
}
}}
if文の中の''exit関数''は、プログラムの実行を終了する関数...
テスト用のコードが間違えていると、正しくテストができませ...
また、テストが終わったらすぐに元に戻せるように、元のプロ...
**演習2 [#s573810c]
プログラム1をプログラム2に変更し、テストを実行せよ。
**ブラック・ボックス・テスト [#lbb3ab44]
コンピューターが問題を正しく作成できることを確認したら、...
コンピュータが問題を正しく生成できることは確認済みなので...
ここでは、実行結果をイメージするときに使った33とします(...
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r, a;
srand((unsigned int) time(NULL)); // 乱数のシード
r = rand() % 100 + 1;
r = 33; // テスト用
a = -1;
while (a != r) {
printf("1から100までの整数を入力してください:\n");
scanf("%d", &a);
if (a > r) {
printf("大きすぎます\n");
} else if (a < r) {
printf("小さすぎます\n");
}
}
printf("正解!\n");
return 0;
}
}}
''ブラック・ボックス・テスト''は、プログラムの中身をわか...
ブラック・ボックス・テスト用のテスト・ケースを作成する方...
''同値分割法''では、入力データを仕様に基づいてグループに...
ここでは、正解よりも大きい数、正解よりも小さい数、正解と...
そこで、正解よりも大きい数の代表として99、正解よりも小さ...
テスト・ケースを選んだら、テスト・ケースを順番に入力し、...
#geshi(sh){{
luna% a.out
整数を入力してください:
99
大きすぎます
整数を入力してください:
11
小さすぎます
整数を入力してください:
33
正解!
}}
''境界値分析''では、境界値を用いてテストを行います。
ここでは、正解よりも小さい数と正解の境界値である32と33、...
テスト・ケースを選んだら、テスト・ケースを順番に入力し、...
#geshi(sh){{
luna% a.out
整数を入力してください:
32
小さすぎます
整数を入力してください:
33
正解!
luna% a.out
整数を入力してください:
34
大きすぎます
整数を入力してください:
}}
**演習3 [#zd2969f9]
ブラック・ボックス・テストの同値分割法と境界値分析を用い...
**ホワイト・ボックス・テスト [#ob534ab6]
''ホワイト・ボックス・テスト''は、プログラムの制御構造に...
ホワイト・ボックス・テスト用のテスト・ケースを作成する方...
''ステートメント・カバレッジ''では、すべての命令文(ステ...
プレイヤーが答えて判定する部分には、1つの代入、4つのprint...
そこで、この6つのステートメントをできる限り多くカバーする...
最初の代入、printf関数、scanf関数は、入力データに関係なく...
2番目の「大きすぎる」と出力するprintf関数は、入力データが...
ここでは、99とします。
3番目の「小さすぎる」と出力するprintf関数は、入力データが...
ここでは、11とします。
最後の「正解」と出力するprintf関数は、入力データが正解に...
ここでは、33です。
テスト・ケースを選んだら、テスト・ケースを順番に入力し、...
#geshi(sh){{
luna% a.out
整数を入力してください:
99
大きすぎます
整数を入力してください:
11
小さすぎます
整数を入力してください:
33
正解!
}}
すべての命令文を実行できたので、このテストのステートメン...
''ブランチ・カバレッジ''(''分岐網羅'')では、フローチャ...
フローチャート2に基づいて、次のようなケースを用意すると、...
+入力された数が正解よりも大きい場合
+入力された数が正解よりも大きくない、かつ、正解よりも小さ...
+入力された数が正解よりも大きくない、かつ、正解よりも小さ...
すると、テスト・ケースは 99, 11, 33 とすればいいことにな...
つまり、このテストは、ステートメント・カバレッジが100%で...
**演習4 [#bbd75a56]
ホワイト・ボックス・テストのステートメント・カバレッジと...
----
*まとめ [#wd06b188]
プログラム作成は、設計、コーディング、テストの順に行いま...
まず、出力結果のイメージを作成し、プログラムの流れをフロ...
フローチャートができたら、フローチャートに基づいてプログ...
プログラムができたら、正しく動くことを確認します(テスト...
ページ名: