C言語入門(8) ループ処理の中断

Posted: 2012年04月22日

ループ処理を中断したいときにはどうすればよいか
例えば、配列のデータを検索する場合

プログラムプログラム:

 bool bFound = FALSE;
 for (int nAryIndex = 0; nAryIndex < sizeof(aryData); nAryIndex++) {
     if (aryData[nAryIndex] == searchData) {
         // 見つかった
         bFound = TRUE;
     }
 }

データが見つかった場合、それ以上ループを続ける必要は無く
無駄に処理をすることになります。

10000データの配列で5回目のループでデータが見つかった場合 9995回無駄になります。
とてもエコじゃない!!

この場合のエコなプログラムをどのように書けばいいか

break文を使用することで解決できます。

break使用例

プログラムプログラム:

 bool bFound = FALSE;
 for (int nAryIndex = 0; nAryIndex < sizeof(aryData); nAryIndex++) {
     if (aryData[nAryIndex] == searchData) {
         // 見つかった
         bFound = TRUE;
         break;
     }
 }

break文を使用することでループを中断することが可能です。
多重ループの場合はどうなるでしょうか
breakの場合は、ひとつのループのみを中断することが出来るため
多重ループを中断する場合は、複数break文を使用します。

プログラムプログラム:

 bool bFound = FALSE;
 for (int nAryIndex = 0; nAryIndex < sizeof(aryData); nAryIndex++) {
     for (int nSubAryIndex = 0; nSubAryIndex < sizeof(aryData[nSubAryIndex]); nSubAryIndex++) {
         if (aryData[nAryIndex][nSubAryIndex] == searchData) {
             // 見つかった
             bFound = TRUE;
             break;
         }
     }
     if (bFound == TRUE) {
         // 見つかったらしいため
         break;
     }
 }

この二重ループで見難くなるため、更に複雑なループになったら更に可読性が落ちます。

一定の条件はあるものの
可読性を高める方法があります。
それは、goto文を使用することです。
goto文は、指定した箇所に移動することができます。
構造を無視した処理を行えるため、評判が悪く一般的にはあまり使用が許されません。(コードレビューで怒られる)
C言語の勉強を行うとGotoはいけない子と教えられますが、なぜダメなのかを教えてくれません。
なぜいけない子になったのか、昔に構造化プログラミングが推奨されるようになり
構造を崩すgotoその他様々な構文を使用してはいけないとダイクストラが言ったため
それが今でも生き続けている感じです。

余談はさておき
gotoの可読性を上げる条件とは、

  • 短い処理のループ文の中断で使用する
  • エラー処理用に使用する

この他の場合で使用すると、プログラマとしての腕を疑われます。

goto使用例

プログラムプログラム:

 bool bFound = FALSE;
 for (int nAryIndex = 0; nAryIndex < sizeof(aryData); nAryIndex++) {
     for (int nSubAryIndex = 0; nSubAryIndex < sizeof(aryData[nSubAryIndex]); nSubAryIndex++) {
         if (aryData[nAryIndex][nSubAryIndex] == searchData) {
             // 見つかった
             bFound = TRUE;
             goto DATA_SEARCH_LOOP;
         }
     }
 }
 DATA_SEARCH_LOOP:

解説解説:

goto ラベル
ラベル:

で構成されています。
goto文は、指定したラベルの行に移動することができます。

ラベル名には、わかりやすいラベルをつけることに力を入れたほうがいいと思います。
とにかくgoto文には、敵が多い為です。

私も、レビューアとして参加したら、理解して使用しているか確認することにしています。

練習練習:

  1. キーボードでqが押された場合のみループを中断するプログラムを作成してください。
    キーボードの入力を取得する関数

char getchar()

カテゴリー: プログラム, 入門 | タグ: , | コメント無し »

コメント