ラベル

goto文をほとんど使わないので、goto文の飛び先のラベルについて、気になることを試してみた。

goto•¶

/* ヘッダファイルのインクルード */
#include <stdio.h> /* 標準入出力 */

/* main関数 */
int main(void){

  /* 変数の宣言 */
  int i; /* ループ変数i */
  int j; /* ループ変数j */

  /* 二重ループ */
  for (j = 0; j < 5; j++){ /* jが5ならこのループは終了. */
    for (i = 0; i < 5; i++){ /* iが5ならこのループは終了. */

      /* iとjの出力. */
      printf("i = %d, ", i); /* iを出力, */
      printf("j = %dn", j); /* jを出力. */

      /* iが1なら二重ループから一気に抜けて, newへ飛ぶ. */
      if (i == 1){ /* iが1の時. */
        goto new; /* gotoでnewに飛ぶ. */
      }

      /* iが2なら二重ループから一気に抜ける. */
      if (i == 2){ /* iが2の時. */
        goto end; /* gotoでendに飛ぶ. */
      }

    }
  }

/* ラベルの設置 */
new: /* newラベル */
  printf("newn"); /* "new"と出力. */

end: /* endラベル */
  printf("endn"); /* "end"と出力. */

  /* プログラムの終了 */
  return 0; /* 0を返して正常終了. */

}

newとendの2つのラベルを用意し、先にnewに飛ぶようにすると、newの下のendは実行されるのかどうか。

$ vi label.c 
$ gcc label.c -o label
$ ./label 
i = 0, j = 0
i = 1, j = 0
new
end
$ 

newに続いてendも実行された。
ということは、switch-case文と同様に、上の処理で止めなければいけない場合が出てくる。

/* ヘッダファイルのインクルード */
#include <stdio.h> /* 標準入出力 */

/* main関数 */
int main(void){

  /* 変数の宣言 */
  int i; /* ループ変数i */
  int j; /* ループ変数j */

  /* 二重ループ */
  for (j = 0; j < 5; j++){ /* jが5ならこのループは終了. */
    for (i = 0; i < 5; i++){ /* iが5ならこのループは終了. */

      /* iとjの出力. */
      printf("i = %d, ", i); /* iを出力, */
      printf("j = %dn", j); /* jを出力. */

      /* iが1なら二重ループから一気に抜けて, newへ飛ぶ. */
      if (i == 1){ /* iが1の時. */
        goto new; /* gotoでnewに飛ぶ. */
      }

      /* iが2なら二重ループから一気に抜ける. */
      if (i == 2){ /* iが2の時. */
        goto end; /* gotoでendに飛ぶ. */
      }

    }
  }

/* ラベルの設置 */
new: /* newラベル */
  printf("newn"); /* "new"と出力. */

  /* 抜ける. */
  break; /* breakで抜ける. */

end: /* endラベル */
  printf("endn"); /* "end"と出力. */

  /* プログラムの終了 */
  return 0; /* 0を返して正常終了. */

}

switch-case文と同様に、breakを入れてみる。

$ vi label.c 
$ gcc label.c -o label
label.c: 関数 ‘main’ 内:
label.c:37:3: エラー: ループまたは switch 文の外にある break 文です
   break; /* breakで抜ける. */
   ^
$ 

しかし、コンパイルエラー。
どうも、breakはwhileなどの繰り返し処理やswitch-case文だけのようである。

となると、return文や、exit関数ぐらいしかないのだろうか。

$ vi label.c 
$ gcc label.c -o label
$ ./label 
i = 0, j = 0
i = 1, j = 0
new
$ 

まあ、こうなるけども。

Sample/c/label/label/src/label at master · bg1bgst333/Sample · GitHub