第7講 for文以外の繰り返し処理

第3話 前話問題解答と解説

前話問題解答例
#pragma endregion
   private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
           //変数の宣言
           int a,b,c,i;
           long w;

           //条件値(はじめの値、合計上限値、変化の幅)を取得
           a=int::Parse(textBox1->Text);
           b=int::Parse(textBox2->Text);
           c=int::Parse(textBox3->Text);

           //初期化
           w=0;
           i=a;

           //1乗の和の計算と表示
           while(w+i<=b){
             w=w+i;
             i=i+c;
           }
           textBox4->Text=w.ToString();

           //2乗の和の計算と表示
           w=0;
           i=a;
           while(w+i*i<=b){
             w=w+i*i;
             i=i+c;
           }
           textBox5->Text=w.ToString();

           //3乗の和の計算と表示
           w=0;
           i=a;
           while(w+i*i*i<=b){
             w=w+i*i*i;
             i=i+c;
           }
           textBox6->Text=w.ToString();

           //4乗の和の計算と表示
           w=0;
           i=a;
           while(w+i*i*i*i<=b){
             w=w+i*i*i*i;
             i=i+c;
           }
           textBox7->Text=w.ToString();

        }
};
}

(赤の部分を本日(2011/07/10)に訂正しました。)

解説
どうです。皆さんうまくいきましたか。
うまくいかなかった方もいらっしゃるのではないでしょうか。
実は前話の課題をwhile文で実行するのは、かなり難しいのです。
私もうっかり最初は次にようにしてしまいました。
#pragma endregion
   private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
           //変数の宣言
           int a,b,c,i;
           long w;

           //条件値(はじめの値、終わりの値、変化の幅)を取得
           a=int::Parse(textBox1->Text);
           b=int::Parse(textBox2->Text);
           c=int::Parse(textBox3->Text);

           //初期化
           w=0;
           i=a;

           //1乗の和の計算と表示
           while(1){
             w=w+i;
             i=i+c;
             if(w>b)break;
           }
           textBox4->Text=w.ToString();

           //2乗の和の計算と表示
           w=0;
           i=a;
           while(1){
             w=w+i*i;
             i=i+c;
             if(w>b)break;
           }
           textBox5->Text=w.ToString();

           //3乗の和の計算と表示
           w=0;
           i=a;
           while(1){
             w=w+i*i*i;
             i=i+c;
             if(w>b)break;
           }
           textBox6->Text=w.ToString();

           //4乗の和の計算と表示
           w=0;
           i=a;
           while(1){
             w=w+i*i*i*i;
             i=i+c;
             if(w>b)break;
           }
           textBox7->Text=w.ToString();

        }
};
}

ところがこれだと実行結果例は、
c++となり、すべてが合計条件値を超えてしまっています。
理由は、if(w>b)break;でループを抜ける判定するときすでに上限値を超えてしまっています。
そこで、if(w>b)break;をif(w=>b)break; と改良したらどうでしょうか。
vc++確かに、1乗の和だけ条件を満たしました。
しかし、2乗以上ではすべて10を超えてしまいました。
理由は、1乗の場合は
1+2+3+4=10なので、if(w=>b)break;でたまたま条件に反せずループを抜け出しただけです。
2乗の場合は、
1の2乗+2の2乗=1+4=5<10なので、ループ処理が続きます。
次の
1の2乗+2の2乗+3の2乗=1+4+9=14でループを抜けることになりますが、
すでに上限値の10を超えてしまっています。
             w=w+i*i;
             i=i+c;
の処理をしてから、判定していることに問題があるのでしょうか。
もし、そうなら次のように改良すれば、問題は解決するはずです。
#pragma endregion
   private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
           //変数の宣言
           int a,b,c,i;
           long w;

           //条件値(はじめの値、終わりの値、変化の幅)を取得
           a=int::Parse(textBox1->Text);
           b=int::Parse(textBox2->Text);
           c=int::Parse(textBox3->Text);

           //初期化
           w=0;
           i=a;

           //1乗の和の計算と表示
           while(1){
             if(w=>b)break;
             w=w+i;
             i=i+c;
           }
           textBox4->Text=w.ToString();

           //2乗の和の計算と表示
           w=0;
           i=a;
           while(1){
             if(w=>b)break;
             w=w+i*i;
             i=i+c;
           }
           textBox5->Text=w.ToString();

           //3乗の和の計算と表示
           w=0;
           i=a;
           while(1){
             if(w>=b)break;
             w=w+i*i*i;
             i=i+c;
           }
           textBox6->Text=w.ToString();

           //4乗の和の計算と表示
           w=0;
           i=a;
           while(1){
             if(w=>b)break;
             w=w+i*i*i*i;
             i=i+c;
           }
           textBox7->Text=w.ToString();

        }
};
}
ところが実行結果は同じです。
入門
なぜでしょうか。
             w=w+i;
             i=i+c;
の処理をする前にループを抜けているのに、なぜうまくいかないのでしょうか。
理由は、簡単です。if(w=>b)break; の判定が行われたとき、2乗以降では上限値の10を超えてしまっているのです。
1の2乗+2の2乗=1+4=5 の次は、1の2乗+2の2乗+3の2乗=1+4+9=14ですでに超えてしまっています。
1の2乗+2の2乗=1+4=5 のとき、5<10でif(w=>b)break;の条件式を満たしませんから、
             w=w+i;
             i=i+c;
の処理は行われてしまうのです。
そして、その処理をした際に、
1の2乗+2の2乗+3の2乗=1+4+9=14で上限値の10を超えてしまうのです。
超えた後に、textBox5->Text=w.ToString();での表示ですから当然14が表示されてしまいます。
つまり、最後の処理
             w=w+i;
             i=i+c;
は余計だったのです。

以上の問題を解決するためには、while(w+i*i<=b)のように条件を変更すればよいのです。




while文が前判定であるのに対して、
後判定を行う処理もあります。
それが、do...while文です。
do{
     ・
     ・
     ・
}while(条件式);

その際の注意は、while文では『}』で終わっているため『;』がいらないのに対して、
do...while文の場合は最後が『)』であるため『;』がいるということです。
;は文の終わりを示しますが、『}』でもC言語は文の終わりと見なしてくれます。
ですから、『}』で終わるときは『;』がいらないのです。
それ以外は、『;』は普通の文の『。』に相当するものなので必ず入れなければなりません。
プログラムをdo...while文で書き直してみましょう。



第2話へ 第4話へ


025


vc++講義へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ



数学研究室に戻る