第1回では,以下の項目に関して学ぶ.
2つの正の整数をキーボードから受けとり,大きな方の数を表示するプログラムのソースコード prog1-1.c
を以下に示す.
prog1-1.c
#include <stdio.h> int main() { int x = -1; int y = -1; printf("Please input two positive integer values: "); scanf("%d %d", &x, &y); if (x > 0 && y > 0) { if (x > y) { printf("The greater value is %d\n", x); } else { printf("The greater value is %d\n", y); } } else { printf("Not positive value(s)\n"); } return 0; }
prog1-1.c
をコンパイルして実行すると,以下のようになる.
% gcc -o prog1-1 prog1-1.c % ./prog1-1 Please input two positive integer values: 10 15 The greater value is 15
prog1-1.c
を実際にコンパイルして,いくつかの値を入力して実行結果を確認せよ.
Makefile を用意しておいたので,それを利用するとコンパイルが楽になる.
make
の実行結果は,以下のようになる.
% make gcc prog1-1.c -o prog1-1 ...
ある関数から,特定の機能を担うコード片を抽出して新たな関数を作成することを関数の抽出という.
ソースコード prog1-1.c
の関数 main()
から,2つの整数を受けとり,それらのうち大きな方を返す関数
int max(int x, int y);を抽出したソースコードを作成する.作成した(不完全な)ソースコード
prog1-2.c
を以下に示す.
prog1-2.c
#include <stdio.h> int max(int x, int y) { return x; } int main() { int x = -1; int y = -1; printf("Please input two positive integer values: "); scanf("%d %d", &x, &y); if (x > 0 && y > 0) { int m = max(x, y); printf("The greater value is %d\n", m); } else { printf("Not positive value(s)\n"); } return 0; }
prog1-2.c
をコンパイルして実行すると,以下のようになる.
% gcc -o prog1-2 prog1-2.c % ./prog1-2 Please input two positive integer values: 10 15 The greater value is 10
この実行結果を見ると,prog1-2.c
の関数 max(int x, int y)
が間違っていることがわかる.
prog1-2.c
の関数max(int x, int y)
が2つの引数のうち大きな方の整数を返すように,ソースコードを修正せよ.
ソースコード prog1-2.c
では,2つの値の大小を比較するコード片だけを関数 max(int x, int y)
として抽出した.
ここでは,ソースコード prog1-1.c
の関数 main()
から,引数として受け取った2つの整数が正であることを確認するコード片も関数 max(int x, int y)
に移動させたソースコードを作成する.作成した(不完全な)ソースコード prog1-3.c
を以下に示す.
prog1-3.c
#include <stdio.h> int max(int x, int y) { return x; } int main() { int x = -1; int y = -1; printf("Please input two positive integer values: "); scanf("%d %d", &x, &y); int result = max(x, y); if (result > 0) { printf("The greater value is %d\n", result); } else { printf("Not positive value(s)\n"); } return 0; }
prog1-3.c
をコンパイルして実行すると,以下のようになる.
% gcc -o prog1-3 prog1-3.c % ./prog1-3 Please input two positive integer values: 10 -1 The greater value is 10
この実行結果を見ると,prog1-3.c
の関数 max(int x, int y)
が間違っていることがわかる.
prog1-3.c
の関数max(int x, int y)
が2つの引数のうち大きな方の正の整数を返すように,ソースコードを修正せよ.どちらかの引数が正の整数でない場合,戻り値は-1
とする.
2つの引数のうち大きな方の正の整数を返す関数 max(int x, int y)
が完成したので,この関数をテストするコードを作成する.
この演習では,テストにおける値の検査に assert
を利用する.そのためには assert.h
をインクルードし,テストしたい評価式を assert
に渡すコード片を記述する.評価式の結果が真(true)の場合はプログラムの実行はそのまま進み,偽(false)の場合は診断メッセージを出力してプログラムの実行が中断される.
assert
によるテストコードを挿入したソースコード prog1-4.c
を以下に示す.
prog1-4.c
#include <stdio.h> #include <assert.h> int max(int x, int y) { return x; } /*=============================================*/ void test1() { assert(max(4, 7) == 7); printf("Success: %s\n", __func__); } int main() { test1(); }
prog1-4.c
をコンパイルして実行すると,以下のようになる.
% gcc -o prog1-4 prog1-4.c % ./prog1-4 Assertion failed: (max(4, 7) == 7), function test1, file prog1-4.c, line 13. Abort
テスト関数 test1()
から呼び出される max(int x, int y)
のコードを見ると,max(4, 7)
の呼出しにおける戻り値として4
(第一引数の x
の値)が返る.これに対して,期待される戻り値(テストの期待値と呼ぶ)は 7
(4
と 7
の大きい方)である.このことを表現しているのが,以下のコード片である.
assert(max(4, 7) == 7);残念ながら,
prog1-4.c
の関数 max(int x, int y)
が間違っているため,この assert
における評価式は偽となり,プログラムの実行が13行目の assert
で中断する.上記の実行結果は,このことを示している.
prog1-4.c
の関数max(int x, int y)
が2つの引数のうち大きな方の正の整数を返すように,ソースコードを修正せよ.prog1-3.c
の関数max(int, int)
が正しく動作するのであれば,それをコピーすればよい.
さらに,関数max(int x, int y)
に対して,2つの引数の値を変えたテスト用の関数 (test2()
,test3()
,...) をprog1-4.c
に追加し,実行結果を確認せよ.
printf("Success: %s\n", __func__);
の__func__
は事前定義識別子であり,関数名が文字列として格納されている(関数の内部のみで使用できるローカル変数である).ここでは,どのテスト関数が成功/失敗しているのかを画面に表示するために,この変数を利用している.
3つの引数のうちもっとも大きな正の整数を返す関数
int max3(int x, int y, int z);と,それに対するテストコードを含むソースコード
prog1-5.c
を作成する.
prog1-5.c
を作成せよ.いずれかの引数が正の整数でない場合,戻り値は-1
とする.テスト関数は3つ以上作成すること.