2001 年度「計算機基礎論3B」 2001-11-13

中カッコのつけかたの見本

9 日の授業で述べた、 while などの“本体”にすべて中カッコを使ったサンプルです。 教科書のサンプルプログラムにこうやって中カッコを補うことは、 みなさんの演習として残すことにしました。

    while (i < 20) {
        ...;
    }
    for (i=0; i<10; ++i) {
        ...;
    }
    if (a < 0) {
        ...;
    }
    if (a < 0) {
        ...;
    } else {
        ...;
    }
    if (a < 0) {
        ...;
    } else if (a == 0) {
        ...;
    } else if (a > 0) {
        ...;
    }
    if (a < 0) {
        ...;
    } else if (a < 1) {
        ...;
    } else if (a < 2) {
        ...;
    } else {
        ...;
    }

else if という特別な構文があるわけではないので、 最後の例は次のように書くのが“正しい”のかもしれないが、 これではどんどん右へ寄ってしまうのでうまくないのだった。

    if (a < 0) {
        ...;
    } else {
        if (a < 1) {
            ...;
        } else {
            if (a < 2) {
                ...;
            } else {
                ...;
            }
        }
    }

演習(の一例)

配列

次のプログラムは、20 個の要素をもつ int の配列 a[ ]を用意し、 一つめの fora[0] には 0 を、a[1] には 1 を、……、 a[19] には 19 を代入し、 二つめの for でそれを出力させている。

== hairetu.c ==================================================================
#include <stdio.h>

main()
{
    int i, a[20];

    for (i=0; i<20; i++) {
        a[i] = i;
    }
    for (i=0; i<20; i++) {
        printf("a[%d] は %d です.\n", i, a[i]);
    }
}
===============================================================================

もしも、上のプログラムで、 配列の宣言はそのままで、 間違えて a[20] まで代入してしまったらどうなるか。 試してみよ。

次のプログラムは、上のプログラムの二つめの for を変更し、 a[0], a[1], ..., a[19] の和を求めている。

== hairetu2.c =================================================================
#include <stdio.h>

main()
{
    int i, a[20], sum;

    for (i=0; i<20; i++) {
        a[i] = i;
    }
    sum = 0;
    for (i=0; i<20; i++) {
        sum = sum + a[i];
    }
    printf("0 から 19 まで足すと %d です.\n", sum);
}
===============================================================================

次のプログラムは、 最初の for で配列 a[ ] を初項 1, 公比 2 の等比数列で埋め、 二つめの for で出力している。 最初の fori=0 からでなく i=1 から始まっていることに注意。

== hairetu3.c =================================================================
#include <stdio.h>

main()
{
    int i, a[40];

    a[0] = 1;
    for (i=1; i<40; i++) {
        a[i] = 2 * a[i-1];
    }
    for (i=0; i<40; i++) {
        printf("a[%d] = %d\n", i, a[i]);
    }
}
===============================================================================
プログラムは正しいが、 ある項で int で表せる範囲を超えるので、 そこからは出力結果が正しくなくなる。

a[0] = a[1] = 1, a[i] = a[i-1] + a[i-2] で定義されるフィボナッチ数列を適当な項まで出力するプログラムを書け。 配列 a[ ]int 型としてもよいが、 float あるいは double として 隣り合った項の比の値も合わせて出力させたらおもしろいかもしれない。

上の hairetu3.c は次のようにすれば配列を使わなくて済む。

== hairetu3b.c ================================================================
#include <stdio.h>

main()
{
    int i, a;

    a = 1;
    for (i=0; i<40; i++) {
        printf("a[%d] = %d\n", i, a);
        a = 2 * a;
    }
}
===============================================================================
ほかのプログラムもこのように書き換えられる。

関数

0 以上の整数 n に対し n の階乗を返す関数 int factorial(int n) を書け。 すぐにできない人はその前に

    int n, f;

    n = 4;
    ...
    printf("%d の階乗は %d です。\n", n, f);
として 「4 の階乗は 24 です」が出力されるようなプログラムを書いてみよ。 それを参考にすればできるはずだ。 また、関数を書くということは、「単に書きました」で終わりではない。 その関数をテストするためのしかるべき main 関数も書く必要がある。

0 以上の整数 n および 0 以上 n 以下の整数 r に対し、 n 個のものから互いに異なる r 個のものを取り出す方法の総数 nCr の値を返す関数 int comb(int n, int r) を書け。 テスト用の main は各自で工夫せよ。 パスカルの三角形が書ければ美しかろう。


岩瀬順一