for文,while文のネストについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
clammbon
記事: 2
登録日時: 1年前

for文,while文のネストについて

#1

投稿記事 by clammbon » 1年前

コード:

#include <stdio.h>
int main(void){
double 
rhofilm =  950000,
tfilm = 0.00000022,
wfilm = 1,
lfilm = 1,
rhohe = 178.6,
rhoair = 1293,
v = 0,
g = 9.86,
mdrone = 32,
mhe,
mfilm,
m,
mair,
fb,
fhe,
vbag,
the;
int i;

for(i=0;i<=2;i++){

    wfilm += 0.1;
    lfilm += 0.1;

    while(1){
        mhe = rhohe*v;
        mfilm = rhofilm*tfilm*wfilm*lfilm;
        m = mhe + 2*mfilm + mdrone*4;
        mair = rhoair*v;
        fb = rhoair*v*g;
        fhe = fb - m*g;

        if(fhe >= 0){
            break;
            }else{
            v = v+0.001;  
        }
    }

    printf("v = %fm^3\n",v);

    while(1){
        vbag = the*wfilm*lfilm;
        if(vbag >= v){
            break;
            }else{
            the = the + 0.001;
        }
    }

    printf("the = %fcm\n",the*100);


}

return 0;

}
以上のコードで

結果が
v = 0.116000m^3
the = 9.600000cm
v = 0.116000m^3
the = 9.600000cm
v = 0.116000m^3
the = 9.600000cm
になってしまいます
結果の予想は
v = 0.116000m^3
the = 9.600000cm
v = 0.116000m^3
the = 8.100000cm
v = 0.116000m^3
the = 6.900000cm
です。
つまり、wfilmとlfilmの値をfor文で更新しているにも関わらず,while文の中身に反映されていないということです。
本当はfor文の部分も無限ループで書いて,

コード:

#include <stdio.h>
int main(void){
double 
rhofilm =  950000,
tfilm = 0.00000022,
wfilm = 1,
lfilm = 1,
rhohe = 178.6,
rhoair = 1293,
v = 0,
g = 9.86,
mdrone = 32,
mhe,
mfilm,
m,
mair,
fb,
fhe,
vbag,
the;
int i;

while(1){


    while(1){
        mhe = rhohe*v;
        mfilm = rhofilm*tfilm*wfilm*lfilm;
        m = mhe + 2*mfilm + mdrone*4;
        mair = rhoair*v;
        fb = rhoair*v*g;
        fhe = fb - m*g;

        if(fhe >= 0){
            break;
            }else{
            v = v+0.001;  
        }
    }

    printf("v = %fm^3\n",v);

    while(1){
        vbag = the*wfilm*lfilm;
        if(vbag >= v){
            break;
            }else{
            the = the + 0.001;
        }
    }

    printf("the = %fcm\n",the*100);

    if(the*100 <= 4){
        break;
    }else{
        wfilm += 0.1;
        lfilm +=0.1;
    }


}

return 0;

}
としたいのですが,今度は一向にbreak せず,無限に続いてしまいます.
おそらくこれも,加算が子のwhile文に反映されていないからだと思います.
どこを直したらよいのか,ご教授ください.

アバター
usao
記事: 1887
登録日時: 11年前

Re: for文,while文のネストについて

#2

投稿記事 by usao » 1年前

デバッグしてください.

コード書きました → コンパイルしました → 思った通りに動きません → はいお手上げ(今ココ)

…ではなくて,
実際にどう動いているのかを確認する作業に入りましょう,という話です.


> つまり、wfilmとlfilmの値をfor文で更新しているにも関わらず,while文の中身に反映されていないということです。

これは実際の変数値や処理の遷移を確認した上で述べているのでしょうか? それとも推測でしょうか?

実際に確認していないならば,各所に printf でも入れてみて動作の様子を観測してください.
(もちろん,デバッガを使えるのであれば,その方が早いですが)
例えば wfilm の値を printf で出力してみれば,きちんと増えていくのが確認できるハズ.
そしたらその変化が「while の中身」にどう効いていくべきなのか?
…っていうのは他者には謎の計算なので不明ですが,あなたは知っているのですから,各計算結果に正しく「反映」されているのかいないのかをチェックできるはず.
チェックしましょう.それだけの話です.

> 今度は一向にbreak せず,無限に続いてしまいます.

というのも同様に,何故 break しないのか? を見ていけばよいだけの話です.
そこは自分自身で確認すべき.

---

一個目のコードを ぱっと見した感じだけで 怪しい点を推測するならば,
出力が変わらないのは「単に,出力値を変化させる処理が実施されないから」だろう,になるんじゃないかな.
要は,if の条件で break の方に行ってるってだけの話じゃないのか? と.
その辺りから見ていけばどうか.
これが何の計算なのかはわからない側からすれば「本当は毎回初期化が必要な変数がいくつか存在するのではないか? (ループ内で値を持ち越しているのが間違いなのでは?)」とか思うけど.

---

あと, 未初期化の the の値をいきなり用いる記述が存在している問題がありますね.

アバター
usao
記事: 1887
登録日時: 11年前

Re: for文,while文のネストについて

#3

投稿記事 by usao » 1年前

ループで値を持ち越すべき変数と,
ループ内部での計算だけに使う変数(次回に持ち越さない)とがあるのなら,
きっちりとそれらを分ければ間違いも減るでしょうし,コードもすっきりするんじゃないかな,と.

例えば,wfilm, lfilm だけがループで値を持ち越すべき存在なのだとしたら,

コード:

for( i=0; i<=2; i++ )
{
  //wfilm, lfilm の値をちょっと増やして計算する
  wfilm += 0.1;
  lfilm += 0.1;
  SomeFunction( wfilm, lfilm );  //指定した wfilm, lfilm の値を用いて何か計算する関数
}
みたいな形でループの内側でやる処理は関数に切り分けてしまえば混在を防げるのではあるまいか.

アバター
usao
記事: 1887
登録日時: 11年前

Re: for文,while文のネストについて

#4

投稿記事 by usao » 1年前

関数に切り出さないとしても,せめてこのくらいに整頓すればどうであろうか.
(現代の C言語 って,このくらいの書き方できるんだよね?)

・定数たるべきものは定数にする.
・各変数のスコープと寿命範囲を必要以上に大きくしない.

コード:

int main(void)
{
	//こいつらは定数
	const double rhofilm =  950000;
	const double tfilm = 0.00000022;
	const double rhohe = 178.6;
	const double rhoair = 1293;
	const double g = 9.86;
	const double mdrone = 32;

	//ループで値を持ち越す変数
	double wfilm = 1;
	double lfilm = 1;

	for( int i=0; i<=2; i++ )
	{
		//wfilm, lfilm の更新
		wfilm += 0.1;
		lfilm += 0.1;

		//v の計算
		double v = 0;
		while(1)
		{
			double mhe = rhohe*v;
			double mfilm = rhofilm*tfilm*wfilm*lfilm;
			double m = mhe + 2*mfilm + mdrone*4;
			double mair = rhoair*v;
			double fb = rhoair*v*g;
			double fhe = fb - m*g;

			if(fhe >= 0){	break;	}
			v += 0.001;
		}
		printf("v = %fm^3\n",v);

		//the の計算
		double the = 0;
		while(1)
		{
			double vbag = the*wfilm*lfilm;
			if(vbag >= v){	break;	}
			the += 0.001;
		}
		printf("the = %fcm\n",the*100);
	}

	return 0;
}

clammbon
記事: 2
登録日時: 1年前

Re: for文,while文のネストについて

#5

投稿記事 by clammbon » 1年前

usao様
丁寧なご回答どうもありがとうございます.
デバック作業を自分でも試してみた末にご質問させていただいたのですが,質問の作法を分かっておらず過程と結果を記述していませんでした.ご指摘ありがとうございます.
”本当は毎回初期化が必要な変数がいくつか存在するのではないか? (ループ内で値を持ち越しているのが間違いなのでは?)”
まさにこのコメントが今回の原因でした.
theとvの値をループのはじめに初期化するとうまくいきました.

コード:

while(1){

    the = 0;
    v=0;

    while(1){

        /*printf("wfilm,lfilm,i=%f,%f,%d\n",wfilm,lfilm,i);*/

        mhe = rhohe*v;
        mfilm = rhofilm*tfilm*wfilm*lfilm;
        m = mhe + 2*mfilm + mdrone*4;
        mair = rhoair*v;
        fb = rhoair*v*g;
        fhe = fb - m*g;

        if(fhe >= 0){
            break;
            }else{
            v = v+0.001;   
        }
    }

    while(1){
        /*printf("wfilm,lfilm,i=%f,%f,%d\n",wfilm,lfilm,i);*/
        vbag = the*wfilm*lfilm;
        if(vbag >= v){
            break;
            }else{
            the = the + 0.001;
        /*printf("wfilm,lfilm,i=%f,%f,%d\n",wfilm,lfilm,i);*/
        }
    }

if(the*100<=4){
    break;
}else{
wfilm = wfilm +0.1;
lfilm = lfilm +0.1;
}
}
定数と,ループで値を持ち越す変数,で分けるなどコードの整頓方法まで教えていただき恐縮です.
言語の習得や質問の作法について学んでまいります.
重ねて感謝申し上げます.ありがとうございます.

返信

“C言語何でも質問掲示板” へ戻る