- ベストアンサー
どなたか分かりますか?
1+2+3+・・・10を計算するプログラムを作るんですが、 #include <stdio.h> int main(){ int a, b; for(a = 0; a<=10; a++){ b=a+1; printf("b=%d\n", b); } return 0; } だと、結果はb=1…b=11と出ます。for文を使わなければいけないんですが、どうすればいいですか?
- みんなの回答 (24)
- 専門家の回答
質問者が選んだベストアンサー
おー!良かったです。 正解です。 >b=0はb=b+a の右辺のbを常に0にするためにあるんですね? 右辺のbを常に0ですか?まだ代入で疑問があるみたいですね。 じゃあ、常にbが0だったらb=0+a;と同じですよね。 正解のプログラムを試しに書き換えてみてください。 望んだ答えが出ましたか?出ないはずです。 じゃあ、箱bは何のためにあるのでしょうか? 箱bに箱aのボールの数を加算していかないと正しい答えが出ないはずです。 そのためにはb=0;と書いて最初に空にする必要があります。あくまで最初だけですよ。 そうしないとint b;で箱bを用意しただけでは箱bの中にボールが何個入っているかが分からないからです。 本当にボールが何個入っているかは運次第で試してみると分かりますが、恐ろしい数値が入っていると思います。 int b; printf("b=%d\n",b); とやってみてください。 main関数だと実行するたびに同じ数値が出ると思いますが、main関数以外で同じことをすると本当に運次第の値になります。 その運次第の値にb=b+a;と実行してしまうと運次第の値にaを足しこんでいくことになるので、結果も望んでいた答えが出ません。 ためしに正解のプログラムからb=0;を除いて実行すると分かると思います。 >で、左辺のbが後に実行されるんですか? それは正解です。 右辺の計算後に左辺に代入されます。 >b+=a;と、b=b+a;は同じですか 同じです。どちらで書いても読みやすければ問題ありません。 最後にこれを実行してみてください。 #include <stdio.h> int main(){ int a,b; b=0; printf("b=%d\n",b); for(a=1;a<=10;a++){ printf("a=%d b=%d\n",a,b); b=b+a; printf("b=%d\n",b); } return 0; } 頭でイメージしている変数の変化と同じ出力が得られましたか? もし違ったら、また質問してみてください。
その他の回答 (23)
- zwi
- ベストアンサー率56% (730/1282)
>これそのものではないんですが、授業で実行結果とプログラムソースを提出するので、例えばこの問題だったら何の合計か分かってもらえますか? 私の表示までする必要は無いでしょう。 この問題だったら途中経過の表示はいらないので printf("b=%d\n",b); をループの後ろに出して合計だけ表示させる方が良いでしょうね。 そのとき表示も printf("合計=%d\n",b); と表示させた方がより分かりやすくて良い回答だと思います。
補足
一歩前進できたと思います。長時間ありがとうございました。
- zwi
- ベストアンサー率56% (730/1282)
>b=0 と入力すれば、空になりますか? 入力された時点で空になります。 入力される前は直前に入れた数値あるいは未初期化なら不定です。 >本題の10までたすプログラムは 中略 >のように、printf("a=%d b=%d\n",a,b);がなくてもいいですか? >ただ、表示の仕方が丁寧ではないので、つけた方がいいですか 不要だと思います。それは変数の変化を追跡するデバッグ用にほしいだけです。 私ならprintfでの表示を工夫して 1+2+3+・・・10=55 と表示させるでしょうね。 変数bをb=55と表示しても何の合計か分かるのはプログラムした人だけですが、上記のように表示すれば誰でもこのプログラムが1~10の合計を表示するためのプログラムだと分かりますから。 良かったら挑戦してみてください。
補足
これそのものではないんですが、授業で実行結果とプログラムソースを提出するので、例えばこの問題だったら何の合計か分かってもらえますか?
- zwi
- ベストアンサー率56% (730/1282)
>これが、変数の初期化という作業ですか? そうです。変数の初期化です。 >確かにb=0を省いたらエラーが出ました。 VC++2005だとワーニング(警告)がでます。 あくまで警告でサッカーのイエローカードですから、そのまま実行できるはずですので実行してみてください。 実行しても英語で初期化されてないよと警告が出ますが、無視ボタンをおせば最後まで実行されます。 すごい数値が表示されませんでしたか? VC++2005は親切ですが、他のコンパイラ(gccなど)では警告も出ない物もあります。 >b=0で箱が空になるということは、0でなければ空でないんですね? 0でないときもあるんですか? 0じゃないのが普通で0であることを期待するのが間違いです。 関数中にint a;などと書いて確保される変数を自動変数と呼びますが、ゆうなれば自動変数は適当なダンボール箱を拾ってきて使いまわす行為です。ボールが入っているかもしれないし入ってないかも知れません。いつも同じ状態(数値)であることを期待するのが間違っています。
補足
b=0 と入力すれば、空になりますか? 本題の10までたすプログラムは #include <stdio.h> int main(){ int a,b; b=0; for(a=1;a<=10;a++){ b=b+a; printf("b=%d\n",b); } return 0; } のように、printf("a=%d b=%d\n",a,b);がなくてもいいですか? ただ、表示の仕方が丁寧ではないので、つけた方がいいですか?
- zwi
- ベストアンサー率56% (730/1282)
>はa=5 b=11と表示されました。しかし、結局int a=1は何のためのものだったんですか? 1は実行結果に反映されていませんが。 はい、反映されません。 別の値に置き換え出来て、最初の値は後の処理に影響を与えない事を知ってもらうのが目的です。 (1)から(6)番の問題もプログラム実行前に頭で考えた値と同じになりましたか?もし考えたのと同じ結果でていれば、代入式の入門は卒業です。 確認できたら、元々の「1+2+3+・・・10を計算するプログラム」に戻りましょう。 今は、b=b+a+1;で合計を計算していますがプログラムとして良いプログラムじゃないので、b=b+a;で計算させた方が良いでしょう。 一度きれいに書き直してみてください。
補足
#include <stdio.h> int main(){ int a,b; b=0; for(a=1;a<=10;a++){ b=b+a; printf("b=%d\n",b); } return 0; } でうまくいきました。b=0はb=b+a の右辺のbを常に0にするためにあるんですね? で、左辺のbが後に実行されるんですか? b+=a;と、b=b+a;は同じですか?
- zwi
- ベストアンサー率56% (730/1282)
>int a=1; >a=3; >はa=3があるので、最初に実行したa=1をなくすために、箱の(1)をとりだしているんですね? 取り出したあとはもう(1)のことは忘れて良いですね? はい、(1)の事は忘れて良いです。 (2)のa=3;から後は箱a内容は3個になりますが、(3)でa=a+2;があるので箱aの中身のボール数は5個になります。(4)~(6)には箱aが左辺に出てこないので箱aは5個のままです。 >int c=3; >c=c+a+3 >のほうは、c=3のあとに「c=数値」がないのでとり出さず、以後も3を使っているんですね? じゃなきゃ3+5+3にならないですよね? はい、その通りです。 ただし、(6)で説明している通り3+5+3の合計11個が箱cに入りますので、(6)から後は箱cの中身はボールが11個になります。 最後の行にprintf("a=%d b=%d\n",a,b);を加えてみると a=5 b=11 と表示されます。 もし理解できた様であれば、もう一度問題をやってみましょう。 問題も少し修正してみました。 1行にまとめて書いてありますが、(1)の問題だと a=0; b=a; printf("a=%d b=%d\n",a,b); と別の行に分けてあるのと同じだと思ってください。 (1)a=0;b=a;printf("a=%d b=%d\n",a,b);の表示されるaとbの値は? (2)a=0;a++;printf("a=%d\n",a);の表示されるaの値は? (3)a=0;a=a+2;printf("a=%d\n",a);の表示されるaの値は? (4)a=0;b=a;a=b+1;printf("a=%d b=%d\n",a,b);の表示されるaとbの値は? (5)a=1;b=2;b=a;printf("a=%d b=%d\n",a,b);の表示されるaとbの値は? (6)a=1;b=2;b=1+a+b+b;printf("a=%d b=%d\n",a,b);の表示されるaとbの値は?
補足
おかげさまで #include<stdio.h> int main(void) {int a=1; a=3; a=a+2; int c=3; c=c+a+3; printf("a=%d b=%d\n",a,c); return 0;} はa=5 b=11と表示されました。しかし、結局int a=1は何のためのものだったんですか? 1は実行結果に反映されていませんが。 (1)a=b=0 実行してみたらそうなりました(2)a=1(3)a=2(4)a=1b=0(5)a=b=1(6)a=1 b=6
- taunamlz
- ベストアンサー率20% (175/843)
NO12です。 >右辺のbと左辺のb結局違うものとして見るのですね?。じゃなかったら 例えばb=0+0+1は0=0+0+1と書けるはずです。 まぁ、そう見れば分かり易いのならそう見ても良いと思います。 自分が初めてプログラミングしたとき、本や教えてくれる人もいませんでしたので人のプログラムをいじってました。 b=b+a+1と言うような意味の式を書きたかったのですが素人だったので c=b+a+1; b=c; と言う2行に分けて書きました。 で、そのうち自分でなんとなく納得できなくなり、cなんか使わなくても書けるんじゃないか?とやってみたらうまく動きました。 >b=b+a+1は数列の一般式のようなものですか? すいません。良く分かりません。 ただ、式の意味はbにb+a+1を代入するという意味です。 >「for文で自動的に値が変化するのは()の中に書いたaと言う変数だけで、{}の中にしか書いていないbの値は計算式を書かない限り変化しません。」とは、結局bは常に0なんですか? そうですね。bの値を変化させたければ for(a = 0; a<=10; a++){ b=a; } 等と書いてやらなければ駄目です。この例の場合「b=a;」と言う一文が無ければbはずーっと同じ値です。でも0とは限りません。for文の前にb=3;と言う式があればbの値はずーっと3です。 >a=a+1とb=b+a+1は同じようなものですか? ニュアンス的には同じようなものです。 b=b+a+1があったとき、a=0ならb=b+1;で変数名が違うだけでa=a+1とまったく同じ動作をします。 b=b+a+1があったとき、a=1ならb=b+2;一度通るたびにbの値が2ずつ大きくなります。 b=b+a+1があったとき、a=2ならb=b+3;一度通るたびにbの値が3ずつ大きくなります。 つまりb=b+a+1;は一度通るたびにbの値がa+1ずつ大きくなります。 b=b*2;だと一度通るたびにbの値が2倍になります。
- zwi
- ベストアンサー率56% (730/1282)
>でも、先程の動作で箱の中の(1)を取り出し、箱の中を0にする操作をしていますよね? これとは違うんですか? int a=1の1の部分は色々な数値に変化しうるんですか? a=1で実行されるんですか? えーと、int a=1;では箱aの名前は右辺に出てきませんよね。左辺に出てきます。前にも書いた通り右辺の箱の中身は変化しませんは、この場合は左辺ですので箱aの中身は変化します。 int a=1; は2行に分解することができます。動作はまったく同じです。 int a; a=1; です。 int a;は箱をa用意しているだけです。 a=1;で箱aにボールを1個入れます。このとき左辺の箱aは一度空にされてから、ボールを1個入れてることになります。 このとき、 int a; a=3; としても全然問題ありません。箱aの中にボールが3個入った状態になります。 >ごめんなさい。関数電卓は持っていません。 分かりました。電卓のメモリー機能は使ったことが無いんですね。
補足
int a=1; a=3; はa=3があるので、最初に実行したa=1をなくすために、箱の(1)をとりだしているんですね? 取り出したあとはもう(1)のことは忘れて良いですね? int c=3; c=c+a+3 のほうは、c=3のあとに「c=数値」がないのでとり出さず、以後も3を使っているんですね? じゃなきゃ3+5+3にならないですよね?
- zwi
- ベストアンサー率56% (730/1282)
>int a=1で、1が入っていた箱の1は取り出して、int c=3で、箱に入った3は取り出さず、次の計算に足し合わせるんですか? まずルールとして、代入式の右辺に出てくる箱(変数)の中身を取り出すことはありません。中身を覗いて個数をチェックしてみて、同じ数のボールを別に用意するだけで箱の中に入っている個数(値)は変化しないのです。 箱の中身が変化するのは、代入式の左辺に出てきた箱だけです。右辺の計算が終わったら、左辺の箱を空箱にします。その上で右辺の計算結果の数のボールを左辺の箱に入れます。数学的に変だと思われるでしょうが、これがC言語のルールです。数学的なルールは無視してください。 >int a=1の後、箱を空にするのは、次の動作に影響がないということですか? (2)のa=3;ことを言ってるのでしょうか?もう少し詳しく質問してもらうと答えられるのですが。 そういえば話は変わりますが、関数電卓は持ってますか?もし日ごろ使っているのであれば、メモリー機能は使いますか? CASIOだとMinとかMRとかM+とか書かれたボタンの機能のことです。これが使いこなせているのであれば、これを使って説明したほうが良い気がしてきました。 日ごろ使っている普通の電卓でもメモリー機能が付いてる物がありますので、使っている電卓のメモリー機能は理解しているか?とメモリー機能に関係したボタンの種類を教えてください。
補足
まずルールとして、代入式の右辺に出てくる箱(変数)の中身を取り出すことはありません> でも、先程の動作で箱の中の(1)を取り出し、箱の中を0にする操作をしていますよね? これとは違うんですか? int a=1の1の部分は色々な数値に変化しうるんですか? a=1で実行されるんですか? ごめんなさい。関数電卓は持っていません。
- zwi
- ベストアンサー率56% (730/1282)
了解しました。数学の思考から脱しきれないみたいですね。 分かってしまえば、目からうろこが落ちるように全てが理解できますから、もう少しがんばってみましょう! じゃあ、基本に戻って変数とは何なのか考えて見ましょう。 話を単純化するために数値変数に限ってたとえ話で説明します。 (1)まず変数とは、数値を入れる箱です。段ボール箱みたいな箱をイメージしてくださいね。変数名は箱にaと書いてあるイメージで。 で、aと書かれた箱に数値1を入れます。数値はボールの数で表しましょう。箱の中身をボールを一個だけにします。 これが、int a=1;です。 (2)続けて、a=3;としましょう。aに3を入れる代入です。 代入は、今まで入っていたボールをすべて捨ててしまって空の状態の箱に値を入れる行為と理解してください。理屈じゃなくそういう動作をします。ボール3個を用意して空箱aの中に入れます。箱aの中身はボール3個になりました。 (3)じゃあ、続いてa=a+2;と書かれていたらと言うと、箱にボールが何個あるのかをまず確認します。さっき3個にしたのでボール3個ですね。 "a+2"という事で箱aの中身と同じ数の3個にもう2個加えて合計5個のボールを用意します。 あとは"a="の代入と言うことで箱aを空箱にして用意してあったに5個のボールを入れます。箱aの中身は5個になりました。 (4)変数cを表す箱cにボールを3個入れておきます。これが、int c=3;です。 (5)c=c+a+3;をたとえ話で書きます。ここが一番ややこしい話になります。 "c+a+3"は、箱cと箱aに入っているのとそれぞれ同じ数のボールを用意します。3個と5個ですね。全部加える計算ですから3+5+3個で合計11個のボールを用意します。で次が問題なので番号を分けます。 (6)代入の"c="が残っています。代入は元々入っている箱cの中身を破棄しますので空箱になります。そこに先ほど計算した11個をいれます。箱cの中身は11個のボールになりました。これがc=c+a+3;です。 以上をプログラムに書くと、 int a=1; a=3; a=a+2; int c=3; c=c+a+3; となります。 今回は、ここまでとしておきます。これができたら次に進みましょう。 分からなくなったり疑問に思ったら各番号で質問してください。
補足
int a=1で、1が入っていた箱の1は取り出して、int c=3で、箱に入った3は取り出さず、次の計算に足し合わせるんですか? int a=1の後、箱を空にするのは、次の動作に影響がないということですか?
- Oh-Orange
- ベストアンサー率63% (854/1345)
★アドバイス ・変数とは何? ここからお勉強した方が良いでしょう。 C言語の本を持っていますか? 持っていないのなら明日、本屋で買った方が良いですけど。 ・ちなみに変数とは一時的に『数』などのデータを覚えておく場所(箱)と イメージして下さい。 『a=0;』は a という名前の箱に『0』というデータを代入します。 『a++;』は a という名前の箱に『1』というデータを加算(加える)処理をします。 よって『a=0;』の次に『a++;』となれば箱の中身は『0』から『1』へ増加します。 for() 文中だけしか変数の値が変化しないわけではありません。 『a++』、『a--』、『a=b+5;』とかすれば a という名前の箱の中身(データ)は 変化します。ここを理解して下さい。 ・以上。絶対に本を用意すべきです。多分持っていないような気がしますので。
補足
そのためにはb=0;と書いて最初に空にする必要があります。あくまで最初だけです。そうしないとint b;で箱bを用意しただけでは箱bの中にボールが何個入っているかが分からないからです。> これが、変数の初期化という作業ですか? 確かにb=0を省いたらエラーが出ました。 b=0で箱が空になるということは、0でなければ空でないんですね? 0でないときもあるんですか?