for文 解答ページ | Programming Place Plus C言語編 第12章

トップページC言語編第12章

問題①

問題① 次の3つの文のうち、実行したあとの変数 x の値がほかと違うのはどれですか?


結果が異なるのは3つ目の x = a--; です。

変数 a の値が 10 だっとすると、1つ目の x = a - 1; では、変数 x は 9 になります。

2つ目の x = --a; は、前置のデクリメントをしていますから、変数 a の値を -1 した後の結果が代入されます。したがって、変数 x は 9 になります。

3つ目の x = a--; は、後置のデクリメントをしていますから、変数 a の値は -1 されますが、代入する値は -1 する前のものです。したがって、変数 x は 10 になります。

実際にプログラムを書いて確認してみます。

#include <stdio.h>

int main(void)
{
    int a;
    int x;

    a = 10;
    x = a - 1;
    printf("%d\n", x);

    a = 10;
    x = --a;
    printf("%d\n", x);

    a = 10;
    x = a--;
    printf("%d\n", x);
}

実行結果:

9
9
10

問題②

問題② 次のプログラムの実行結果はどうなりますか?

#include <stdio.h>

int main(void)
{
    for (int i = 0; i < 0; ++i) {
        puts("Hello");
    }
}


一定回数だけ繰り返す for文としては典型的な使い方をしています。

繰り返す回数が i < 0; となっており、これは「0回繰り返す」という意味です。したがって、この for文の {} の内側は1度も実行されません。実行結果はこうなります。

実行結果:

なお、for文の {} の内側が1度も実行されないとしても、int i = 0; と、「条件式」である i < 0 は実行されていることに注意してください(処理内容からいって、結局、何も起こりませんが)。for文全体がすべて無視されるような動作になるわけではありません。

問題③

問題③ 次のプログラムの実行結果はどうなりますか?

#include <stdio.h>

int main(void)
{
    int value = 0;

    for (int i = 0; i < 5; ++i) {
        value += i;
    }
    printf("%d\n", value);
}


こちらも典型的な for文で、繰り返す回数は 5回です(i < 5;)。for文の内側では、変数 value に対して、+ i を行っています。

変数 i の値は、for文が1周するたびにインクリメントされますから、初回は 0、次の周回では 1、さらにその次の周回では 2 ・・・ というふうに増加します。したがって、行われている計算は次のようなものです。

  1. value += 0;
  2. value += 1;
  3. value += 2;
  4. value += 3;
  5. value += 4;

5回くりかえしたら終わりですから、ここまでです。

変数 value の初期値は 0 なので、最終的には 10 になっています。

実行結果:

10

問題④

問題④ for文を使って、2 から順に 2 のべき乗を出力するプログラムを作成してください(21、22、23、24・・・つまり 2、4、8、16・・・と出力します)。10個出力したところで終了してください。


たとえば、次のようになります。

#include <stdio.h>

int main(void)
{
    int value = 1;

    for (int i = 0; i < 10; ++i) {
        value *= 2;
        printf("%d\n", value);
    }
}

実行結果:

2
4
8
16
32
64
128
256
512
1024

10個出力したら終わりにしたいので、条件式を i < 10 とした for文を構築します。

for文の内側では、出力する値をつくりつつ、printf関数に渡して出力していきます。出力する値は、変数 value に入れています。

for文が1周するたびに 2倍していけば、2 のべき乗が求められます。1個目の出力が 2 になるように、初期値を 1 にしておくことを忘れないようにしましょう。初期値を 2 で始めて、次のように書いても同じ結果を得られます。

#include <stdio.h>

int main(void)
{
    int value = 2;

    for (int i = 0; i < 10; ++i) {
        printf("%d\n", value);
        value *= 2;
    }
}

実行結果:

2
4
8
16
32
64
128
256
512
1024

問題⑤

問題⑤ 整数の入力を繰り返し受け取り、そのつど、現時点までの合計と平均を出力するプログラムを作成してください。全部で5回入力されたら終了とします。


たとえば、次のようになります。

#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)
{
    int total = 0;

    for (int i = 0; i < 5; ++i) {
        puts("Please enter the integer.");
        int value = get_input_integer();

        total += value;

        printf("total: %d\n", total);
        printf("average: %d\n", total / (i + 1));
    }
}

実行結果:

Please enter the integer.
3  <-- 入力した整数
total: 3
average: 3
Please enter the integer.
5  <-- 入力した整数
total: 8
average: 4
Please enter the integer.
10  <-- 入力した整数
total: 18
average: 6
Please enter the integer.
6  <-- 入力した整数
total: 24
average: 6
Please enter the integer.
6  <-- 入力した整数
total: 30
average: 6

合計を求めるために、変数 total を宣言し、0 で初期化します。この変数は for文の外側で宣言しなければならないことに注意してください。

for文の内側では、整数の入力を受け取るたびに、変数 total にその値を加算していきます。これでいつも、現時点での合計値が total に入っていることになります。

平均値の方は、「合計 / 個数」で求められます。個数をカウントするための変数を導入してもいいですが、変数 i が同じ役割を果たしていますから、これを使っています。ただし、変数 i は 0 で開始されているので、total / (i + 1) のようにして、1つ加算した値を使う必要があります。

問題⑥

問題⑥ 九九の表を出力するプログラムを作成してください。つまり、次のような出力結果が得られるようにしてください。

1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81


2つのループがあることに気がつくでしょうか?

まず、1行目の「1 2 3 4 5 6 7 8 9」は、1 から順に 1 ずつ増えており、9個の数があります。

次の行には「2 4 6 8 10 12 14 16 18」となっており、これは 2 から順に 2 ずつ増えており、やはり 9個の数があります。

このように1行ずつ数列を出力することを、全部で 9回繰り返している様子がみえます。つまり、各行の横方向にループがあり、縦方向にもループがあるという構図になっています。ループが2つあるので、for文も2つ必要です。また、各行の処理の中でループしなければならないのですから、ループの最中にループしていることも分かります。

ソースコードに書き下すとこうなります。

#include <stdio.h>

int main(void)
{
    for (int i = 0; i < 9; ++i) {
        for (int j = 0; j < 9; ++j) {
            printf("%d ", (i + 1) * (j + 1));
        }
        printf("\n");
    }
}

実行結果:

1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81

最初にあらわれる for文にとっての「繰り返したい文」の中に、2つ目の for文が現れるという構造です。このようなループは、多重ループ (multiple loops) と呼ばれます。

for文が繰り返される回数は、いずれも9回ずつですから、i < 9j < 9 という条件式になっています。変数 i が重複してしまわないように、内側の for文では、j という名前の変数を使っています(これも典型的な名前付けです)。

変数 i と j は 0 から始まっているため、そのまま乗算すると目的の結果が得られないので、それぞれ +1 してから掛け合わせています。これは、本編での for文の使い方にしたがうようにしたためです。別に、変数 i や j の初期値を 0 にしなければならないというルールがあるわけではありませんので、次のように書いても構いません。

#include <stdio.h>

int main(void)
{
    for (int i = 1; i < 10; ++i) {
        for (int j = 1; j < 10; ++j) {
            printf("%d ", i * j);
        }
        printf("\n");
    }
}

実行結果:

1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81


参考リンク


更新履歴



第12章のメインページへ

C言語編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る