4-7 <発展> ループを制御する文

この記事は約6分で読めます。

本トピックは発展的な内容を扱うので飛ばして構いません。一通りC言語の学習を終えてから見ることをお勧めします。

break文

これまでに何度か登場しましたが、break(ブレイク)文はループから抜け出すという意味です。このbreakは英語で中断という意味です。break文はswitch文、while文、do-while文、for文の中でのみ使用可能で、break;とすると最も内側のswitch文、while文、do-while文、for文から抜け出すことができます。ただし、複数のループから一気に抜け出すことはできません。if文やif-else文は関係ありません。

#include <stdio.h>
int main(void){
	int i,a;
	do {
		puts("正の整数を入力してください。0を入力すると終了します。");
		scanf("%d",&a);
		if (a>0){
			puts("カウントダウン");
			for (i=a;;i--){
				printf("%d",i);
				if (i==0) break;
			}
			printf("\n");
		}
	} while (a!=0);
	return 0;
}

実行結果

正の整数を入力してください。0を入力すると終了します。
3
カウントダウン
3210
正の整数を入力してください。0を入力すると終了します。
-8
正の整数を入力してください。0を入力すると終了します。
0

11行目のbreak文は最も内側のforループから脱出するという意味です。外側のdo-while文から抜け出すことはできません。

continue文

break文と似た意味を持つ物としてcontinue(コンテニュー)文があります。continueは英語で継続するという意味です。continue文はwhile文、do-while文、for文の中でのみ使用可能で、ループ処理を途中でスキップして次のループに移るという意味です。

while文の中でcontinue文を使った場合

#include <stdio.h>
int main(void){
	int i=1,a;
	while (i<=5) {
		puts("正の整数を入力してください。");
		scanf("%d",&a);
		if (a<=0) continue;
		if (a%2) puts("aは奇数です");
		else puts("aは偶数です。");
		i++;
	}
	return 0;
}

実行結果

正の整数を入力してください。
6
aは偶数です。
正の整数を入力してください。
5
aは奇数です
正の整数を入力してください。
-5
正の整数を入力してください。
2
aは偶数です。
正の整数を入力してください。
0
正の整数を入力してください。
3
aは奇数です
正の整数を入力してください。
1
aは奇数です

for文の中でcontinue文を使った場合

#include <stdio.h>
int main(void){
	int i=1,a;
	for (i=1;i<=5;i++) {
		puts("正の整数を入力してください。");
		scanf("%d",&a);
		if (a<=0) continue;
		if (a%2) puts("aは奇数です");
		else puts("aは偶数です。");
	}
	return 0;
}

実行結果

正の整数を入力してください。
6
aは偶数です。
正の整数を入力してください。
5
aは奇数です
正の整数を入力してください。
-5
正の整数を入力してください。
2
aは偶数です。
正の整数を入力してください。
0

while文とfor文とで挙動が違います。while 文でcontinue文を使用するとループの最後のi++;が実行されないのでcontinue;をした回数は5回までのループには入りません。一方for文ではi=1から5までの5回のループと指定しています。for文でcontinue;するとi++は実行されるので、0以下の整数を入力しても5回のループにカウントされます。

goto文

goto文はbreak文やcontinue文と違ってどの場所にでも移動できるものです。

ラベル名:
goto ラベル名;

goto文を使用するとラベル名が書かれたところまでジャンプします。goto文を使用すると好きなところへジャンプするので一見使いやすいように感じますが、多用しすぎるとプログラムの流れが分かりにくくなります。流れがわかりにくくなったプログラムを俗にスパゲッティプログラムと呼びます。ですから初めてC言語を学ぶ人は安易にgoto文を使わない方がいいでしょう。ちなみに筆者は5年間のプログラミング生活において2回goto文を使ったことがあります。筆者の場合、多重ループから一気に抜け出すときに使用しました。

#include <stdio.h>
int main(void){
	int i=1,a;
	while (1) {
		puts("正の整数を入力してください。0を押すと終了します。");
		scanf("%d",&a);
		if (!a) goto end;
		if (a%2) puts("aは奇数です");
		else puts("aは偶数です。");
	}
	end:
	return 0;
}

実行結果

正の整数を入力してください。0を押すと終了します。
3
aは奇数です
正の整数を入力してください。0を押すと終了します。
6
aは偶数です。
正の整数を入力してください。0を押すと終了します。
0

0入力するとgoto文が実行され、endラベルまで移ります。

ジャンプ命令

setjmp(),longjmp()をつかってジャンプすることも可能ですが、かなりマニアックな文法であり筆者は使用したことがありません。

longjmp()を呼び出すとsetjmp()関数が使用された場所へ強制的にジャンプされます。jmp_buf型の変数を定義し、プログラムの実行コンテキスト(CPUの状態のことです。)を格納します。また、これらの関数を使用するには#include <setjmp.h>が必要です。

#include <stdio.h>
#include <setjmp.h>
jmp_buf jmpbuf;
void func(void)
{
	puts("func:start");
	longjmp(jmpbuf,10);
	puts("func:end");
}
int main()
{
	int context=setjmp(jmpbuf);
	puts("main:start");
	if (context==0) {
		func();
	}else{
		printf("context:%d\n",context);
	}
	puts("main:end");
	return 0;
}

実行結果

main:start
func:start
main:start
context:10
main:end

goto文と同様に、頻繁に使用するとプログラムの流れがわかりにくくなるので使用することはお勧めできません。ただ、エラーが発生したときの処理として使用されることがあるそうです。C++などの言語にはエラーが発生した場合に例外処理を行うことができますが、この例外処理はC言語のsetjmp,longjmpがもととなっています。

コメント

タイトルとURLをコピーしました