苦しんで覚えるC言語

入力チェック


後判定と先判定


C言語には、全部で3つのループ文が用意されています。
while文、for文、そして、do(デュウ)~while文です。

while文とfor文については既に説明しましたが、
実は、do~while文は、while文とほとんど同じです。
do~while文は、一般に、次のような書き方で使用します。

do {
繰り返す文;
} while (条件式);
条件式の意味も動作も、while文と全く同様です。
すなわち、条件式が真の間、繰り返す文の実行を繰り返すのです。
なお、書き方の違いとして、do~while文の場合には、
while文の条件式の()の後に;が必要になります。

do~while文とwhile文の唯一の違いは、
条件式が、後判定であるか先判定であるかの違いです。
while文は、繰り返す文の実行を行う前に条件式を判定します。
しかし、do~while文は、繰り返す文の実行後に条件式を判定します。

実は、これだけでは、あまり大きな違いにはなりません。
実際、while文でもdo~while文でも、同じ結果になることもあります。
その為、do~while文はあまり使われていません。

しかし、do~while文には、1つ大きな利点があります。
それは、繰り返し文が、必ず1回は実行されるという点です。

while文の場合、もしも初めから条件式が偽になっていたら、
繰り返し文が1回も実行されないまま終わってしまうことになりますが、
do~while文ならば、最低でも1回だけは実行されます。

目次に戻る

入力チェック


do~while文の、必ず1回は実行されるという利点は、
なんと言っても、入力チェックの時に威力を発揮します。

例えば、円の面積を計算するプログラムを作ってみます。
円の面積は、半径x半径x円周率です。
ここで、半径が負の値と言うのはおかしいですから、それをチェックします。
円周率はいくつ
コンピュータの世界では、円周率を3.14159で計算します。
これは、その次の桁まで表すと、3.141592、となり、
9と2の間で切り捨てても、誤差が大きくならないからです。
次は、ループを使用しない場合のチェックです。

#include <stdio.h>

int main(void)
{
	
	int r;
	double s;
	
	printf("半径?:");
	scanf("%d",&r);
	if (r < 0) {
		printf("半径は負の値になりません。\n");
	} else {
		s = r  r  3.14;
		printf("面積は %f です。\n",s);
	}
	
	return 0;
}
このプログラムを実行し、8を入力した結果は次の通りです。

半径?:8
面積は 200.960000 です。
このプログラムを実行し、-8を入力した結果は次の通りです。

半径?:-8
半径は負の値になりません。
これでも一応チェックは出来ていますが、ちょっと不親切です。
入力値が間違っているならば、再入力させるのが普通です。
次のプログラムは、while文で再入力を実装した例です。

#include <stdio.h>

int main(void)
{
	
	int r;
	double s;
	
	printf("半径?:");
	scanf("%d",&r);
	
	while (r < 0) {
		printf("半径?:");
		scanf("%d",&r);
	}
	
	s = r  r  3.14;
	printf("面積は %f です。\n",s);
	
	return 0;
}
このプログラムを実行し、-8、-5、8 を入力した結果は次の通りです。

半径?:-8
半径?:-5
半径?:8
面積は 200.960000 です。
見事に再入力が行われています。
しかし、今度の問題は、プログラム側にあります。
プログラムを見ると、scanf関数を2回使っていることがわかります。
同じデータの入力なのに、scanf関数を2回書くのはまさに無駄です。
次のプログラムは、do~while文でこの無駄をなくした例です。

#include <stdio.h>

int main(void)
{
	
	int r;
	double s;
	
	do {
		printf("半径?:");
		scanf("%d",&r);
	} while (r < 0);
	
	s = r  r  3.14;
	printf("面積は %f です。\n",s);
	
	return 0;
}
このプログラムを実行し、-8、-5、8 を入力した結果は次の通りです。

半径?:-8
半径?:-5
半径?:8
面積は 200.960000 です。
今度は、scanf関数は1回だけ書けば済みます。
必ず1回は実行されるという、do~while文の利点が生かされています。

目次に戻る