ループ

C言語勉強会 第四回

kumar
May 13, 2013
引用 : Programming Place Plus

ループ(反復)ありなしで比較してみる

ループを使わなかった場合

クソ長くてページに収まらない

#include <stdio.h>

int main(void) {
    char c;

    printf("1文字入力してください:");
    scanf("%c", &c);

    /* 10回出力する */
    printf("%c\n", c);
    printf("%c\n", c);
    printf("%c\n", c);
    printf("%c\n", c);
    printf("%c\n", c);
    printf("%c\n", c);
    printf("%c\n", c);
    printf("%c\n", c);
    printf("%c\n", c);
    printf("%c\n", c);

    return 0;
}

ループを使って書きなおすと

#include <stdio.h>

int main(void) {
    char c;

    printf("1文字入力してください:");
    scanf("%c", &c);

    /* 10回出力する */
    int i = 0;
    while(i < 10) {
        printf("%c\n", c);
        i++;    /* iに1を足す。(インクリメントという) */
    }

    return 0;
}

スッキリ!!その気になれば10000回ループも簡単

while文

条件式が真である限り繰り返す文

while文の構造)

while( 条件式 ){
    ループさせる処理
}

「条件式」の部分には、「処理を繰り返すのはどんなときか」を記述します。

while文

実行される処理の順序

  1. 「条件式」を調べる。「真」なら2へ。「偽」なら4へ。
  2. 「ループさせる処理」を実行する。3へ。
  3. 「ループさせる処理」が全て終了したら1へ戻る。
  4. while文を終了させて、次の処理へ進む。

while文

ページ「ループを使ってみると」の例より抜粋)

/* 10回出力する */
int i = 0;
while(i < 10) {
    printf("%c\n", c);
    i++;    /* iに1を足す。(インクリメントという) */
}

どのように動作してこのコードで処理が10回繰り返されるのか、イメージしてみましょう。

より高機能なループ文がある

#include <stdio.h>

int main(void) {
    char c;

    printf("1文字入力してください:");
    scanf("%c", &c);

    /* 10回出力する */
    int i;
    for(i = 0; i < 10; i++) {
        printf("%c\n", c);
    }

    return 0;
}

状況によりwhile文よりもさらに短く書ける!!

for文

while文よりも高機能なループ文

for文の構造)

for( 初期設定式; 条件式; 再設定式 ){
    ループさせる処理
}

for文

実行される処理の順序

  1. 「初期設定式」を実行。2へ。
  2. 「条件式」を調べる。「真」なら3へ。「偽」なら6へ。
  3. 「ループさせる処理」を実行する。4へ。
  4. 「ループさせる処理」が全て終了したら5へ。
  5. 「再設定式」を実行。2へ戻る。
  6. for文を終了させて、次の処理へ進む。

for文

ページ「より高機能なループ文がある」の例より抜粋)

/* 10回出力する */
int i;
for(i = 0; i < 10; i++) {
    printf("%c\n", c);
}

再び、どのように動作してこのコードで処理が10回繰り返されるのか、イメージしてみましょう。

do文(do-while文)

do文では、ループ内の処理が必ず1度は実行される。

do文の構造)

do{
    ループさせる処理
} while( 条件式 );

while文やfor文では、条件式が負の場合、ループ内の処理が1度も実行されないことがあるのですが、do文では、ループ内の処理が必ず1度は実行されます。

ご察しの通り、ループさせる処理を実行してから、条件式を評価してループを継続するか判断します。

他のループ文に比べて、使う機会が非常に少ないループ文です。

goto文

同じ関数内の別の場所へ一気に移動させる。 移動先はラベルで表現する。

※この文は使ってはならない。とよく言われます。goto文は(同じ関数内であれば)どこへでも移動できるため、処理の流れが非常に分かりにくくなる可能性が高いからです。どうしても使いたい場合はいいですがやめておきましょう。

    goto ラベル名;

ラベル

ラベル名:

goto文の例

#include <stdio.h>

int main(void) {
    int i = 0;
unko:    /* これがラベル */
    if(i >= 5) {
        goto final_unko;    /* iが5以上ならラベルfinal_unkoへジャンプ */
    }
    printf("変数iは今 %d\n", i);

    i++;
    goto unko;  /* ラベルunkoへジャンプ */

final_unko:

    return 0;
}

無限ループ

永遠に繰り返されるループ

無限ループの例)

while( 1 ){
    printf("unko\n");
}

このプログラムを実行すると、永遠にunkoと出力され続ける。(ちなみに、Ctrl + Cで、端末で実行中のプログラムを強制終了できる。)

常に真になる"1 > 0"の結果は1と同じである。

break;

ループ文を、中断して抜ける。

前のページの「無限ループの例」を、while文の条件式を true から変えずに、break文を使って、5回だけ出力するように書き換えてみる。

int i = 0;
while( 1 ){
    if(i >= 5) {
        break;
    }
    printf("unko\n");
    i++;
}

if文を使い、i が 5 (以上)になったとき、break を発動させ、ループを中断して抜けだした。
ちなみに、switch文も抜け出すことができる。

continue;

現在のループを打ち切り(後続の処理を無視して)次のループへ進ませる

for文の場合は「再設定式」が実行されてから、次へ進みます。 次のループへ進んだとき、当然「条件式」がチェックされます。これが偽になれば、ループ全体を終えることになります。

int i;
for(i = 0; i < 5; i++) {
    scanf(" %c", &c);
    if(c == 'a') {
        count++;
        continue;
    }
    /* continueされた場合continueより下に書かれているので実行されない */
    printf("aを入力しろよ!!!次から気をつけろよ!!!\n");
}

諸々 1

for文の構造)

for( 初期設定式; 条件式; 再設定式 ){
    ループさせる処理
}

これは、通常のwhile文に文を多少加えた

初期設定式;
while( 条件式 ){
    ループさせる処理
    再設定式;
}

と同じ動きをしています。今までの内容から気づいていた人も多いかと思います。

諸々 2

また、for文の初期設定式と再設定式は省略が可能です。例えば、

for( ; 条件式 ; ){
    ループさせる処理
}

このように両方省略する事もでき、御察しの通り、while文と同じ動きになります。

また、条件式も省略可能です。この場合、ループ内でbreakやreturnを実行することにより、ループを抜けます。

諸々 3

for文の初期設定式において、変数を宣言することが可能。

ページ「for文」の例を改変)

    for(int i = 0; i < 10; i++) {
        printf("%c\n", c);
    }

int iをfor文の外で宣言せずに、初期設定式の中で宣言している。行数が減って楽である。(ただし、C99以前では不可能。

諸々 4

ループ文もif文と同様に、処理が1行であるなら中括弧{}を省略できる。

for( 初期設定式; 条件式; 再設定式 )
    ループさせる処理

ループ文の中にループ文を入れ子(ネスト)して書くことが出来る。

while( 条件式 ){
    ...
    while( 条件式 ){
        ...
    }
    ...
}