第10講 for文以外の繰り返し(ループ)処理
第4話 合計の上限値を越えない等差数列の和
を実現するプログラム例
#include<iostream>
using namespace std;
int f1(int h,int j,int k);
int f2(int h,int j,int k);
int f3(int h,int j,int k);
long f4(int h,int j,int k);
void main(){
int h,j,k,i,w; //hははじめの値(初項)、jは合計の上限値、kは変化の幅(公差)
cout<<"はじめの値は?"<<endl;
scanf("%d",&h);
cout<<"合計の上限値は?"<<endl;
scanf("%d",&j);
cout<<"変化の幅?"<<endl;
scanf("%d",&k);
if(f1(h,j,k)>0){
cout<<"1乗の和="<<f1(h,j,k)<<endl;
}
else{
cout<<"初項の段階で上限値を越えています。"<<endl;
}
if(f2(h,j,k)>0){
cout<<"2乗の和="<<f2(h,j,k)<<endl;
}
else{
cout<<"初項の段階で上限値を越えています。"<<endl;
}
if(f3(h,j,k)>0){
cout<<"3乗の和="<<f3(h,j,k)<<endl;
}
else{
cout<<"初項の段階で上限値を越えています。"<<endl;
}
if(f4(h,j,k)>0){
cout<<"4乗の和="<<f4(h,j,k)<<endl;
}
else{
cout<<"初項の段階で上限値を越えています。"<<endl;
}
}
int f1(int h,int j,int k){
int i,w;
i=h;
w=0;
while(1){
w=w+i;
if(w>j){
w=w-i;
break;
}
i=i+k;
}
return(w);
}
int f2(int h,int j,int k){
int i,w;
i=h;
w=0;
while(1){
w=w+i*i;
if(w>j){
w=w-i*i;
break;
}
i=i+k;
}
return(w);
}
int f3(int h,int j,int k){
int i,w;
i=h;
w=0;
while(1){
w=w+i*i;
if(w>j){
w=w-i*i*i;
break;
}
i=i+k;
}
return(w);
}
long f4(int h,int j,int k){
int i;
long w;
i=h;
w=0;
while(1){
w=w+i*i;
if(w>j){
w=w-i*i*i*i;
break;
}
i=i+k;
}
return(w);
}
解説
どうです。皆さんうまくいきましたか。
うまくいかなかった方もいらっしゃるのではないでしょうか。
実は前話の課題をwhile文で実行するのは、かなり難しいのです。
私もうっかり最初は次にようにしてしまいました。
#include<iostream>
using namespace std;
int f1(int h,int j,int k);
int f2(int h,int j,int k);
int f3(int h,int j,int k);
long f4(int h,int j,int k);
void main(){
int h,j,k,i,w; //hははじめの値(初項)、jは合計の上限値、kは変化の幅(公差)
cout<<"はじめの値は?"<<endl;
scanf("%d",&h);
cout<<"合計の上限値は?"<<endl;
scanf("%d",&j);
cout<<"変化の幅?"<<endl;
scanf("%d",&k);
if(f1(h,j,k)>0){
cout<<"1乗の和="<<f1(h,j,k)<<endl;
}
else{
cout<<"初項の段階で上限値を越えています。"<<endl;
}
if(f2(h,j,k)>0){
cout<<"2乗の和="<<f2(h,j,k)<<endl;
}
else{
cout<<"初項の段階で上限値を越えています。"<<endl;
}
if(f3(h,j,k)>0){
cout<<"3乗の和="<<f3(h,j,k)<<endl;
}
else{
cout<<"初項の段階で上限値を越えています。"<<endl;
}
if(f4(h,j,k)>0){
cout<<"4乗の和="<<f4(h,j,k)<<endl;
}
else{
cout<<"初項の段階で上限値を越えています。"<<endl;
}
int f1(int h,int j,int k){
int i,w;
i=h;
w=0;
while(1){
w=w+i;
i=i+k;
if(w>j)break;
}
return(w);
}
int f2(int h,int j,int k){
int i,w;
i=h;
w=0;
while(1){
w=w+i*i;
i=i+k;
if(w>j)break;
}
return(w);
}
int f3(int h,int j,int k){
int i,w;
i=h;
w=0;
while(1){
w=w+i*i*i;
i=i+k;
if(w>j)break;
}
return(w);
}
long f4(int h,int j,int k){
int i;
long w;
i=h;
w=0;
while(1){
w=w+i*i*i*i;
i=i+k;
if(w>j)break;
}
return(w);
}
ところがこれだと実行結果例は、
となり、すべてが合計上限値を超えてしまっています。
理由は、if(w>j)break;でループを抜ける判定するときすでに上限値を超えてしまっています。
そこで、if(w>j)break;をif(w=>j)break; と改良したらどうでしょうか。
確かに、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+k;
の処理をしてから、判定していることに問題があるのでしょうか。
もし、そうなら次のように改良すれば、問題は解決するはずです。
#include<iostream>
using namespace std;
int f1(int h,int j,int k);
int f2(int h,int j,int k);
int f3(int h,int j,int k);
long f4(int h,int j,int k);
void main(){
int h,j,k,i,w; //hははじめの値(初項)、jは合計の上限値、kは変化の幅(公差)
cout<<"はじめの値は?"<<endl;
scanf("%d",&h);
cout<<"合計の上限値は?"<<endl;
scanf("%d",&j);
cout<<"変化の幅?"<<endl;
scanf("%d",&k);
if(f1(h,j,k)>0){
cout<<"1乗の和="<<f1(h,j,k)<<endl;
}
else{
cout<<"初項の段階で上限値を越えています。"<<endl;
}
if(f2(h,j,k)>0){
cout<<"2乗の和="<<f2(h,j,k)<<endl;
}
else{
cout<<"初項の段階で上限値を越えています。"<<endl;
}
if(f3(h,j,k)>0){
cout<<"3乗の和="<<f3(h,j,k)<<endl;
}
else{
cout<<"初項の段階で上限値を越えています。"<<endl;
}
if(f4(h,j,k)>0){
cout<<"4乗の和="<<f4(h,j,k)<<endl;
}
else{
cout<<"初項の段階で上限値を越えています。"<<endl;
}
}
int f1(int h,int j,int k){
int i,w;
i=h;
w=0;
while(1){
if(w>=j)break;
w=w+i;
i=i+k;
}
return(w);
}
int f2(int h,int j,int k){
int i,w;
i=h;
w=0;
while(1){
if(w>=j)break;
w=w+i*i;
i=i+k;
}
return(w);
}
int f3(int h,int j,int k){
int i,w;
i=h;
w=0;
while(1){
if(w>=j)break;
w=w+i*i*i;
i=i+k;
}
return(w);
}
long f4(int h,int j,int k){
int i;
long w;
i=h;
w=0;
while(1){
if(w>=j)break;
w=w+i*i*i*i;
i=i+k;
}
return(w);
}
ところが実行結果はで同じです。
なぜでしょうか。
w=w+i*i;
i=i+k;
の処理をする前にループを抜けているのに、
なぜうまくいかないのでしょうか。
理由は、簡単です。
if(w=>j)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=i+k;
の処理は行われてしまうのです。
そして、その処理をした際に、
1の2乗+2の2乗+3の2乗=1+4+9=14で上限値の10を超えてしまうのです。
超えた後に、
cout<<"2乗の和="<<f2(h,j,k)<<endl;
での表示ですから当然14が表示されてしまいます。
つまり、最後の処理
w=w+i*i;
i=i+k;
は余計だったのです。
以上の問題を解決するためには、
while(1){
w=w+i*i;
if(w>j){
w=w-i*i;
break;
}
i=i+k;
}
等としなければならないのです。
足したときに上限値を超えています。
最後の足し算が余計なわけですから、
差し引いてもとに戻してから終了しなければならないわけです。
また、
if(f4(h,j,k)>0){
cout<<"4乗の和="<<f4(h,j,k)<<endl;
}
else{
cout<<"初項の段階で上限値を越えています。"<<endl;
}
等に?に方もいらっしゃると思います。
これは、はじめの値が3、上限値が20だとすると、
3の4乗で81ですから、はじめから上限値を超えているわけです。
解答例の
long f4(int h,int j,int k){
int i;
long w;
i=h;
w=0;
while(1){
w=w+i*i*i*i;
i=i+k;
if(w>j)break;
}
return(w);
}
だと0を返してきますので、
if(f4(h,j,k)>0){
cout<<"4乗の和="<<f4(h,j,k)<<endl;
}
else{
cout<<"初項の段階で上限値を越えています。"<<endl;
}
などとしています。
while文が前判定であるのに対して、
後判定を行う処理もあります。
それが、do...while文です。
do{
・
・
・
}while(条件式);
その際の注意は、while文では『}』で終わっているため『;』がいらないのに対して、
do...while文の場合は最後が『)』であるため『;』がいるということです。
;は文の終わりを示しますが、『}』でもC言語は文の終わりと見なしてくれます。
ですから、『}』で終わるときは『;』がいらないのです。
それ以外は、『;』は普通の文の『。』に相当するものなので必ず入れなければなりません。
プログラムをdo...while文で書き直してみましょう。
第3話へ 第5話へ
魔方陣 数独で学ぶ VBA 入門
数独のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 C++ 入門 基礎から応用まで第1部
eclipse java 入門
java 入門 サイト 基礎から応用まで
VC++ C言語 C++ 入門 初心者 基礎から応用まで
本サイトトップへ