ページ 11

質問です~。

Posted: 2007年3月24日(土) 11:57
by いさご
こんにちは。いさごです。
While loopで{}を付け忘れた場合どうなるか宿題がでました。
自分でやってみたところ、コンパイルは出来たのですが、
whileの部分でプログラムが止まり、終了できなくなりました。
考えてみたのですが、実際に中で何が起きているのかよく分かりません。
どなたか教えていただけませんか?

Re:質問です~。

Posted: 2007年3月24日(土) 13:10
by 組木紙織
if(/*判定*/) /*内容*/
と
if(/*判定*/){
 /*内容*/
}
を比べてみてください。

Re:質問です~。

Posted: 2007年3月25日(日) 09:25
by いさご
回答ありがとうございます。

ifでの結果は二つとも同じでした。
一本道を進むだけであれば{}の有無は影響しないということでしょうか・・・?
ただwhileの場合、whileの条件を満たしているのに、
{}を忘れるとwhileの中身が一度も実行されないのがどうしてなのかまだわかりません。
一度実行してから止まるなら想像は付くのですが・・・。
すみません。

Re:質問です~。

Posted: 2007年3月25日(日) 10:41
by 管理人
if文で書く上記/*内容*/の部分を色々変更してコンパイルしてみてください。
カッコがあるかないかでどのようにかわるのか確認するためにこのようなプログラムを書いてみました。

それぞれの大きなカッコは一つ一つのプログラムに分かれていることを強調したものです。
#include <stdio.h>

int main(){

	{
		printf("1\n");
		if(1==1)
			printf("2\n");
		printf("3\n");
		if(1==2)
			printf("4\n");
		printf("5\n");
	}

	{
		int i=0,a=0;
		while(i<10)
			i++;
		a++;
		a++;
		printf("a=%d\ti=%d\n",a,i);
	}

	{
		int i,a=0;
		for(i=0;i<10;i++)
			a++;
		a++;
		a++;
		printf("a=%d\ti=%d\n",a,i);
	}

	return 0;
}
このプログラムをじっくり見て、どのように処理が行われるからこうような出力になるのか考えてみてください。

Re:質問です~。

Posted: 2007年3月25日(日) 12:17
by いさご
丁寧な回答ありがとうございます。
書いてくださったプログラムをあちこち弄繰り回してみて、
なんとなく分かった気がしました。
whileの場合、条件の更新がwhileの真下にあればその部分だけループされる、と言う事でしょうか。

int i=0,a=0;
 while(i<10)
a = a + i
i++;
printf("a=%d\ti=%d\n",a,i);

私の書いたプログラムは簡略化するとこんな感じだったため、
while部分でプログラムが止まったのだと思われます。
この考えで合っているのか不安ですが・・・。

Re:質問です~。

Posted: 2007年3月25日(日) 13:29
by box
while(i<10)
		a = a + i;
	i++;

は、

	while(i<10) {
		a = a + i;
	}
	i++;

と等価です。
while文によるループの中で、i < 10 という条件を
ずっと満たし続ける(i の値を更新していない)ため、
プログラムは無限ループします。
止まっているのではなく、「実行しっぱなし」なのです。

Re:質問です~。

Posted: 2007年3月26日(月) 03:58
by 管理人
boxさんのおっしゃっている「実行しっぱなし」を目で見てわかるようにしたのが下のプログラムです。
whileの条件をちょっといじくって「a++;かi++;がどちらか20億回計算されたら終了」するようにしてあります。
(プログラムの意味を直訳すると「iの値もaの値もどちらも20億より小さい時ループ」)

PCのスペックによってはずっと黒い画面のままだと思いますので、気長に何か表示されるまで待ってください。
この黒い画面のままのときは裏でひたすら計算が行われているのです。(20億回もね。)
 
#include <stdio.h>

int main(){
	long int i=0,a=0;
	while(i<2000000000 && a<2000000000)
		a++;
	i++;
	printf("a++;は%10d回計算されました。\ni++;は%10d回計算されました。\n",a,i);
	return 0;
}
 

>whileの場合、条件の更新がwhileの真下にあればその部分だけループされる、と言う事でしょうか。

その通りです。
whileに限らず、カッコを省略するものにはそれが適応される事が多いです。
if文であったり、for文であったり、while文であったり。

カッコを沢山書くとうっとうしいので、よく1行しか実行する文が無い時は省略して書きます。
for(i=0;i<10;i++){
        for(j=0;j<10;j++){
                if(i==j){
                        printf("iとj同じ\n");
                }
        }
}

これと

for(i=0;i<10;i++)
        for(j=0;j<10;j++)
                if(i==j)
                        printf("iとj同じ\n");

これは同じことです。
書いてある次の行のみ有効になります。
基本的に「次の;まで」だと思ってください。
 

Re:質問です~。

Posted: 2007年3月26日(月) 21:36
by いさご
boxさん、管理人さん、丁寧な回答ありがとうございます。
とても良くわかりました。わかるとループって意外と楽しいですね。
ループを書くときに気をつける点も同時に理解できたと思います。
ありがとうございました!