第4章 制御構造・1

1 構造化プログラミングとは?

 プログラム作りにある程度のルールを定め、 誰が作っても同じ品質の分かりやすいプログラムになるようにしようという手法。

1-1制御構造の種類

順次
判断
(if else)
他方向分岐
(switch case)
前判定反復
(while)
後判定反復
(do while)
所定回反復
(for)

※基本的には「順次」「選択」「反復」の3種類しかない!

1-2 フローチャートの書き方

使い方
開始、終了
プログラムの開始、終了を表す。
準備
変数の宣言、初期値の代入を表す。
処理
通常の文を表す。
入力
標準入力装置(キーボード)からのデータの入力を表す(scanfなど)。
出力
標準出力装置(CRT)への出力を表す(printfなど)。
条件分岐
条件による処理の分岐を表す(if文など)。
反復(loop)の開始、終了
反復処理の開始、終了を表す。回と終了のどちらに条件文を書くかにより、前判定、後判定に分かれる。

1-3 フローチャートとプログラムを書いてみよう

点数を入力し、入力された点数を表示する。

[フローチャート]

[プログラム]

/* 入力された点数を表示する */
#include <stdio.h>
main()
{
    int     ten;

    printf("点数 ? ");
    scanf("%d", &ten);
    printf("入力された点数 : %d\n", ten);

}

2 条件判断(if else文)

 ある条件を満たすか満たさないかにより処理を分ける手法。

2-1 if文

フローチャート 書式
if (条件式)
{
  文1;
}

[解説]

  1. ifの後ろの括弧内にある条件式を調べ、もし式が正しければ文1を実行する。
    (条件を満たした時の式の値を、満たさなかった時の値をという)
  2. 文1が1行しかない場合、「」「」を省略して書くことができる。

[例題1]

整数変数tenの値が60未満なら「追試」と表示するプログラム。

/* 追試かどうかを調べるプログラム*/
#include <stdio.h>
main()
{
    int ten = 59;

    if (ten < 60)
    {
        printf("追試\n");
    }

}
6行目のif文で変数tenの値が60未満かどうか調べ、条件が正しければ「追試」を出力するprintf文が実行される。

2-2 if else文

フローチャート 書式
if (条件式)
{
  文1;
}
else
{
  文2;
}

[解説]

  1. ifの後ろの括弧内にある条件式を調べ、もし式が正しければ文1を、正しくなければ式2を実行する。

[例題2]

整数変数yearの値が20以上なら「成年」、そうでなければ「未成年」と表示するプログラム。

/* 成年かどうかを調べるプログラム*/
#include <stdio.h>
main()
{
    int     year = 18;

    if (year >= 20)
    {
        printf("成年\n");
    }
    else
    {
        printf("未成年\n");
    }

}
6行目のif文で変数yearの値が20以上かどうか調べ、条件が正しければ「成年」を出力するprintf文が、正しくなければelse文の後にある「未成年」を出力するprintf文が実行される。

2-3 関係演算子

条件文を記述する際、大小関係などを判断する演算子を関係演算子と呼ぶ。

主な関係演算子
演算子意味
〜より大きい
>=〜より大きいか、等しい(〜以上)
〜より小さい(〜未満)
<=〜より小さいか、等しい(〜以内)
==〜と同じ(等しい)
!=〜以外(等しくない)

※〜と同じかどうかを調べるのは「==」であり、「=」ではないことに注意!
(例えば条件文としてa = 10とすると、通常の代入文になってしまい、a == 10の意味にはならない)

2-4 ブロックについて

 文がいくつか集まった論理的なひとかたまりをブロックといい、 「」「」で囲む。

2-5 if文を使ってみよう

入力された点数を表示する。ただし60点未満の場合、点数の後ろに「追試決定」と表示する。

[フローチャート]

[プログラム]

/* 入力された点数を表示する */
#include <stdio.h>
main()
{
    int     ten;

    printf("点数 ? ");
    scanf("%d", &ten);
    printf("入力された点数 : %d\n", ten);
    if (ten < 60)
        printf("  追試決定");
    printf("\n");

}

練習問題

教科書50ページ例題6及び練習問題6のフローチャートを書き、プログラムを実行。

2-5 if文のネスト(入れ子)

if文の中にif文を書くことができる。

フローチャート 書式
if (条件式1)
{
  if (条件式2)
    {
        文1;
    }
    else
    {
        文2;
    }
}
else
{
    文3;
}

[例題3]

入力した年(西暦)が閏年か普通年かを判定する。判定は次のとおり。

[閏年の求め方]
4で割り切れたら閏年。
ただし、100で割り切れたら閏年ではない。
ただし、400で割り切れたら閏年。
[フローチャート]
[プログラム]
/* 閏年判定プログラム */
#include <stdio.h>
main()
{
    int     year;

    printf("西暦を入力:");
    scanf("%d", &year);
    if (year%4 == 0)
    {
        if (year%100 == 0)
        {
            if (year%400 == 0)
            {
                printf("西暦 %d 年は閏年\n", year);
            }
            else
            {
                printf("西暦 %d 年は普通年\n", year);
            }
        }
        else
        {
            printf("西暦 %d 年は閏年\n", year);
        }
    }
    else
    {
        printf("西暦 %d 年は普通年\n", year);
    }

}

3 ループ(繰り返し)処理(while文、for文)

 ある条件を満たしている間、処理を繰り返す手法。

3-1 while文(前判定ループ文)

くり返し回数が決まっていない繰り返しを行うための手法。

フローチャート1 フローチャート2 書式
while (条件)
{
  文;
}

[解説]

  1. 条件を満たしている間、{}内の処理を繰り返す。
    条件によっては一度も文を実行せずにくり返し文を抜ける場合がある。
  2. 文が1行しかない場合、「」「」を省略して書くことができる。

[例題1]

1から10までの数値を表示するプログラム。

/* 1から10までの数値を表示 */
#include <stdio.h>
main()
{
    int     number;

    number = 1;
    while (number<=10)
    {
        printf("%d\n", number);
        number++;
    }

}
  • 初期値として、numberに1を入れる。
  • 7行目のwhile文により、くり返し処理が始まる。
  • numberが10以下の場合、処理を繰り返す。(条件)
  • while文の最後でnumberに1を加算する。(この処理が無いと永久ループになる)

練習問題

設問1
教科書57ページ例題9のフローチャートを書き、プログラムを入力、実行せよ。
設問2
1から100までの数値で奇数のみを表示するプログラムを作成せよ。
(ヒント)初期値を1、増分を2にセットしてwhile文をまわす。
設問3
教科書57ページ練習問題9のプログラムを完成させよ。
設問4
2のべき乗(2^1, 2^2, 2^3, ・・・, 2^n)を求めるフローチャートを書き、プログラムを作成せよ。
ただし、計算結果が100000を超えたらプログラムを終了すること。
実行結果例
2^1 = 2
2^2 = 4
2^3 = 8


3-2 for文(指定回数ループ文)

くり返し回数があらかじめ決まっているときに使う手法。

フローチャート1 フローチャート2 書式
for (式1;条件;式2)
{
  文;
}

[解説]

  1. 条件を満たしている間、{}内の処理を繰り返す。
  2. 式1は、ループに入る前に一度だけ実行される。通常はくり返し回数を格納する変数(ループ変数)の初期化に使用する。
  3. 式2は、{}内の文が処理されるたびに実行される。通常はループ変数のカウントアップに使用する。
  4. 文が1行しかない場合、「」「」を省略して書くことができる。

[例題1]

1から10までの数値を表示するプログラム。

/* 1から10までの数値を表示 */
#include <stdio.h>
main()
{
    int     number;

    for (number=1 ; number<=10 ; number++)
    {
        printf("%d\n", number);
    }

}
  • 6行目のfor文により繰り返し処理が始まる。
  • 初期値として、numberに1を入れる。(式1)
  • numberが10以下の場合、処理を繰り返す。(条件)
  • printfが実行されるたびに、numberに1が加算される。(式2)

練習問題

設問1
教科書54ページ例題8のフローチャートを書き、プログラムを入力、実行せよ。
設問2
while文の練習問題設問2のプログラムを、for文に改造せよ。
設問3
’A’から’Z’までの文字を横に表示するプログラムを作成せよ。
設問4
教科書55ページ練習問題8のプログラムを完成させよ。

3-3 くり返し文のネスト

while文やfor文も、if文と同じようにネストさせることができる。

フローチャート1フローチャート2

[例題]

1から10までの数字と、数字分の*を表示するプログラム。

[フローチャート]
[プログラム]
/* 1から10までの数値と*を表示 */
#include <stdio.h>
main()
{
    int     number, i;

    for (number=1 ; number<=10 ; number++)
    {
        printf("%02d : ", number);
        for (i=1 ; i<=number ; i++)
        {
            printf("*");
        }
        printf("\n");
    }

}

練習問題

上記例題のプログラムを、while文で作成せよ。

4 複雑な条件式

 条件をいくつか組み合わせた複雑な条件式の書き方を解説する。

4-1 複雑な条件式

例えば得点を入力するプログラムがあるとして、 入力された数値が0以上100以下かどうかを調べる場合、 数学の書き方では、

0 ≦ 数値 ≦ 100

と書くが、プログラミングの世界では「≦」という記号が存在しないため、

0 <= 数値 <= 100

と書く。ところがプログラミングでの条件式はこのような書き方はできないので、 この条件式をプログラムで書くと、今までは、

if (0 <= ten)
    if (ten <= 100)
        printf("入力データは正しい\n");

と書くことしかできなかった。これは、論理演算子を使うと、

if (0 <= ten && ten <= 100)
  printf("入力データは正しい\n");

と書くことができる。

4-2 論理演算子

いくつかの条件式を組み合わせるものを論理演算子と呼び、次の3種類がある。

演算子 意味 ベン図 書き方
否定(NOT)
条件を満たさないものが真
条件を満たすものが偽
!(条件式)
&& かつ(AND)
条件1と条件2を共に満たすものが真
それ以外が偽
条件式1 && 条件式2
|| または(OR)
条件1と条件2のどちらかを満たしていれば真
それ以外が偽
条件式1 || 条件式2

練習問題

  1. 教科書52ページ問4
  2. 教科書52ページ練習問題7
    (ただし、putchar(c)はprintf("%c", c)に置き換える)
  3. うるう年判定プログラム(HP第4章2例題3)をif文1つで判定できるよう作り変える

5 データの終わりとEOF

 入力データに対して何かの処理を行い、 データが終わるまで繰り返すというプログラムを作る方法を解説する。

5-1 考え方

データが終わるまで処理を繰り返すというプログラムを作る場合、 データの終わりを表す値を決め、その値が入力されるまで処理を繰り返せばよい。

例、-9999が入力されるまで処理を繰り返す
フローチャートプログラム

scanf("%d", &data);
while (data != -9999)
{
    処理;
    scanf("%d", &data);
}

5-2 EOF

標準入力関数は、^Z(CTRL+Z)が入力されると、EOFという値を返すように作られている。EOFは「ファイルの終わり」を表し、例えばテキストファイルからデータを読み込んで処理をする場合、データがなくなると入力関数はEOFを返す。
よって、scanf関数の戻り値がEOF以外のときに処理を繰り返すようプログラムを作ればよい。

例、CTRL+Zが入力されるまで処理を繰り返す

プログラム1プログラム2
int     ret;
ret = scanf("%d", &data);
while (ret != EOF)
{
    処理;
    ret = scanf("%d", &data);

}
while (scanf("%d", &data) != EOF)
{
    処理;

}

第4章 確認問題

  1. 制御構造の3つの基本形は何?
  2. 条件判断に使う命令は何?
  3. ループ処理に使う命令は何?
  4. 条件Aまたは条件Bのいずれかが成り立つという条件文はどう書く?
  5. 条件Aと条件Bの両方が成り立つという条件文はどう書く?
  6. 入力関数(scanf)を繰り返し使うとき、データが終わったことを教えるには何を入力する?
  7. 入力関数(scanf)がデータの終わりを検出したとき、どんな値が返る?
  8. 九九の表を出力するプログラムは?

[ TOP ]