WisdomSoft - for your serial experiences.

3.4 while文

while 文は条件が真の間、指定したコードを繰り返し実行します。ここでは while 文を用いた反復処理の制御方法を解説します。

3.4.1 ループを作る

プログラムの制御において、分岐と同様に極めて重要な存在が繰り返し処理です。複雑な計算や検索など、実践のプログラムでは何度も使われるので、しっかりと基本を身につける必要があります。繰り返し処理は、特定の文を指定した条件が満たされるまで繰り返すことで実現します。これを行う最もシンプルな方法が while 文を用いた方法です。

while は if 文に似た構文で、条件式が真であれば指定した文を繰り返すというものです。逆に言えば while は条件式の評価結果が偽、すなわち 0 になるまで文を繰り返し実行します。 

while文
while (条件式) 

条件式が偽になるまで文が実行されるため、通常は while の文で条件式に影響する変数などを操作してカウンターの役割を持たせます。カウンターとなる変数を用いることで、文を繰り返す回数や、現在何回目の繰り返しなのかを知ることができます。

コード1
#include <stdio.h>

int main() {
	int iCount;
	printf("繰り返す回数を入力してください>");
	scanf("%d" , &iCount);

	while(iCount > 0) {
		printf("カウンタ = %d\n" , iCount);
		iCount--;
	}
	return 0;
}
実行結果
コード1 実行結果

コード1を実行すると、リピート回数が求められるので数値を入力します。while は入力された値を格納する iCount を評価して、これが 0 以上であれば文を繰り返し実行します。while の本体文では、カウンターの値を表示し、その後にカウンターの値をデクリメントしています。これを何度も繰り返していれば、カウンターはいつか 0 になり、ループを抜け出します。

無限ループとなってしまった場合はプログラムを終了させる手段がありません。途中で強制的にループから抜け出したい場合は、while が評価している条件式が偽になるようにカウンタを操作するか、break 文を用いて while から強制的に抜け出すことができます。break 文は制御を抜け出す機能があるため、現在のループから抜け出すことができます。

コード2
#include <stdio.h>

int main() {
	int iCount = 0;
	while(1) {
		if (iCount == 1000) break;
		printf("iCount = %d\n" , iCount++);
	}
	return 0;
}
実行結果
コード2 実行結果

コード2は、意図的に while の条件式を 1 (真)にすることで無限ループにし、while を抜け出す手段として break 文を用いています。iCount 変数の値を繰り返す度にインクリメントし、これが 1000 に達した時に抜け出します。

インクリメント処理は printf("iCount = %d\n" , iCount++);  で行われています。初心者にとってはあまり慣れない書き方かもしれないので、少し解説します。これは、2行に分けて次のように書くこともできるのですが、このプログラムではあえて printf() 関数の引数でインクリメントしています。

printf("iCount = %d\n" , iCount);
iCount++;

このように書いて問題はありませんが、筆者は解説書などで長いソースプログラムを見るとげんなりしてしまうので、必要のない処理や冗長な部分はカットするように努力しています。そこで、上の2行を1行にまとめてしまう方法として、printf() 関数の引数として指定している iCount に注目し、printf() が評価されたあとにインクリメントされるように後置きインクリメント演算子を使ったのです。後置きインクリメント演算子は変数を評価したあとにインクリメントを行うという性質があったことを思い出してください。

因みに、while のような繰り返し制御は入れ子構造にしても問題はありません。実践的なプログラムでは、複雑なアルゴリズムやグラフィック処理などで、頻繁に入れ子になった繰り返し制御を行います。

while (expr1) {
	while (expr2) {
		...
	}
}

こうした入れ子構造の繰り返し処理は、アプリケーション開発では決して珍しいことではありません。例えば 2 次元の情報に対して計算を行うときは、繰り返し処理を入れ子構造にして順に計算させる方法がとられます。これは、2次元のコンピュータグラフィックスに対して全体的な処理を行うときなどに応用することができるでしょう。次のプログラムは九九の表を作り、画面に表示します。

コード3
#include <stdio.h>

int main() {
	int iOp1 = 1 , iOp2 = 1;

	while (iOp1 < 10) {
		while(iOp2 < 10) {
			printf("%2d " , iOp1 * iOp2);
			iOp2++;
		}
		printf("\n");
		iOp2 = 1;
		iOp1++;
	}
	return 0;
}
実行結果
コード3 実行結果

コード3を実行すると九九の表が出力されます。

因みに printf() 関数の書式制御で %2d という表現がありますが、この 2 という数字は文字幅指定を行っています。この場合は %d を指定したときと同様に整数値を表示しますが、文字幅を指定しているため、最小でも2文字分の幅を使って数値を表示します。1桁の場合は2文字に満たないため空白で埋められます。これは単純に九九の表を美しく表示するために使っただけで、特に重要ではありません。

3.4.2 ループの先頭に戻る

何らかの事情で、繰り返し処理の複合文の内部で処理を中断して、次の繰り返しに移行したい場合があります。つまり、現在の繰り返しはその時点で終了して、while 文の先頭に戻り、式を評価したいという状況です。

これを実現するには continue 文を用います。これを使えば、文本体の残りの処理を実行せずにループの先頭に戻ることができます。 

コード4
#include <stdio.h>

int main() {
	int iCount = 0;

	while(iCount++ < 100) {
		if (iCount % 2) continue;
		printf("%d " , iCount);
	}
	return 0;
}
実行結果
コード4 実行結果

このプログラムは、画面に偶数のみを表示するというものです。カウンタ変数である iCount の 2 で割った余りが 0 以外のとき、これはすなわち奇数の時であると考えられるので、iCount % 2 を求めて、これが真であれば continue 文を使って残りの処理を無視します。その結果、printf() が実行されるのは、iCount が偶数の時のみとなります。