第1回では,以下の項目に関して学ぶ.

  1. 関数の抽出
  2. テストコードの作成

課題のソースコードのテンプレート:

課題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
...

課題2: 関数の抽出(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つの引数のうち大きな方の整数を返すように,ソースコードを修正せよ.

課題3: 関数の抽出(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 とする.

課題4: テストコードの作成

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 (47 の大きい方)である.このことを表現しているのが,以下のコード片である.

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__ は事前定義識別子であり,関数名が文字列として格納されている(関数の内部のみで使用できるローカル変数である).ここでは,どのテスト関数が成功/失敗しているのかを画面に表示するために,この変数を利用している.

課題5: 関数とテストコードの作成

3つの引数のうちもっとも大きな正の整数を返す関数

int max3(int x, int y, int z);
と,それに対するテストコードを含むソースコード prog1-5.c を作成する.

prog1-5.c を作成せよ.いずれかの引数が正の整数でない場合,戻り値は -1 とする.テスト関数は3つ以上作成すること.
この課題はありません.
この課題はありません.
この課題はありません.
Go to Top