- ベストアンサー
どなたか分かりますか?
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)
zwiです。2つの質問に答えてもらっていないのが残念です。ほんとに間違いを解消しなくて大丈夫ですか?後で困りませんか?と問いかけておきます。たぶん、目の前のひとつのことしか考えられない状態なのだと思いますが。 さて、何度もみなさんが言ってますが代入式の"="は数学の"="とは意味がまったく違います。数学の"="は左辺と右辺が等しい事を表しますが、代入式の"="は右辺の計算結果を左辺に代入しますと言う意味でしかありません。C言語の代入式は"="と考えずに、b←b+a+1と書かれていると思ってください。頭の中の数学的な常識を一時的に棚上げする必要があります。 あとは、左辺と右辺に同じ変数が出てきたときの >b=b+a+1 >右辺のbと左辺のb結局違うものとして見るのですね? の回答ですが、C言語は時間的に右辺の処理を先に行います。aに0、bに0が入っていた場合は、0+0+1が先に計算されます。計算結果は1です。その後左辺の処理として計算結果1をbに代入しますので結果としてbに1が入ります。ここでbが1になりますが、右辺の処理が既に終了しているので計算結果に影響を与えることは起こりません。bは1のままです。 >「for文で自動的に値が変化するのは()の中に書いたaと言う変数だけで、{}の中にしか書いていないbの値は計算式を書かない限り変化しません。」とは、結局bは常に0なんですか? の問いかけは、 >b=0; >for(a = 0; a<=10; a++){ >printf("b=%d\n", b); >} というプログラムの事ならYESです。 >int a, b = 0; >for(a = 0; a<10; a++){ >b = b + a + 1; >printf ("b=%d\n", b); >} というプログラムの事ならNOです。 最後に何問か質問します。これの答えで理解度が分かると思います。 (1)a=0;b=a;と書かれていた場合のaとbの値は? (2)a=0;a++;と書かれていた場合のaの値は? (3)a=0;a=a+2;と書かれていた場合のaの値は? (4)a=0;b=a;a=b+1;と書かれていた場合のaとbの値は? (5)a=1;b=2;b=a;と書かれていた場合のaとbの値は? (6)a=1;b=2;b=1+a+b+b;と書かれていた場合のaとbの値は? 逆にこの答えが全て分からないと代入式を理解したことにはなりません。
補足
(1)aもbも常に0 (2)これはいずれもfor文の外ですか?aは常に0なのでaは1ずつ増やしようがありません。←間違っていると思いますが、(2)から(6)は同じようなので、こういう風にしか回答できません。こういう風に勘違いしているというのを示したくて書きました。ごめんなさい。 投稿していていただいた >b=0; >for(a = 0; a<=10; a++){ >printf("b=%d\n", b); >} と >int a, b = 0; >for(a = 0; a<10; a++){ >b = b + a + 1; >printf ("b=%d\n", b); >} の類題ですか?
- taunamlz
- ベストアンサー率20% (175/843)
No1です。 プログラムがどんな動きをしているかをもう一度考えてみてはどうでしょう? 例えば for(a = 0; a<=10; a++){ b=a+1; } と書いたとします。これを分解して書くと b=0+1; b=1+1; b=2+1; b=3+1; b=4+1; b=5+1; b=6+1; b=7+1; b=8+1; b=9+1; b=10+1; と言うプログラムとまったく同じです。だからb=1…b=11と表示されました。 次に b=0; for(a = 0; a<10; a++){ b=b+a+1; } と書いたとします。これを分解して書くと b=0; b=b+0+1; b=b+1+1; b=b+2+1; b=b+3+1; b=b+4+1; b=b+5+1; b=b+6+1; b=b+7+1; b=b+8+1; b=b+9+1; と言うプログラムとまったく同じです。 念のためbに数字を入れて書くと b=0+0+1; b=1+1+1; b=3+2+1; b=6+3+1; b=10+4+1; b=15+5+1; b=21+6+1; b=28+7+1; b=36+8+1; b=45+9+1; と言う計算をしている事になります。 これだと1~10までを足したプログラムとなりますので、期待通りの動きをすると思います。 for文の意味を考えて見ます。 for(a = 0; a<=10; a++){ } と言う文が有ります。この文は (まずaに0を代入しなさい。;a<=10の条件を満たしている間は{}の中を繰り返しなさい;一度ループするたびにa++の計算をしなさい) と言う意味です。 さて、a++とは何でしょうか? a++はa=a+1と言う計算式とまったく同じものです。 for(a = 0; a<=10; a=a+1){ と書いても同じです。 つまり、aを1ずつ増やしなさいと言う式なのです。 補足を読むとbも自動的に1ずつ増えそうな事を書いています。 b=0; for(a = 0; a<=10; a++){ printf("b=%d\n", b); } と言うプログラムを書いて実行してみましょう。結果は b=0 と言う表示が11個表示されると思います。 for文で自動的に値が変化するのは()の中に書いたaと言う変数だけで、{}の中にしか書いていないbの値は計算式を書かない限り変化しません。 さて、間違えて覚えていそうな部分を思いつく限り書いてみました。 まだ分からない事があれば補足してください。
補足
aを1ずつ増やしていくことは分かります。 ただ、肝心のb=b+a+1がどうしても分かりません。 右辺のbと左辺のb結局違うものとして見るのですね?。じゃなかったら 例えばb=0+0+1は0=0+0+1と書けるはずです。 b=b+a+1は数列の一般式のようなものですか? 「for文で自動的に値が変化するのは()の中に書いたaと言う変数だけで、{}の中にしか書いていないbの値は計算式を書かない限り変化しません。」とは、結局bは常に0なんですか? a=a+1とb=b+a+1は同じようなものですか?
- zwi
- ベストアンサー率56% (730/1282)
あっごめんなさい。 書き間違いに気づきました。 >代入式で理解すべきことは左辺が先に実行されることです。b+a+1が計算されてその結果の値がbに代入されるのが代入式です。 これは右辺ですね。申し訳ないです。 edomin2004さんの書き込みで間違いに気づきました。 私の書いた文で左辺と書いてあるところは右辺と読み直してください。 混乱させていたら申し訳ないです。
- zwi
- ベストアンサー率56% (730/1282)
zwiです。 >bも結局0から1ずつ増やしているんですよね? いえ、プログラムの何処にもそんなことは書いていないです。 プログラムで変数の値に影響を与えているのは次の3行だけです。 >int a, b = 0; >for(a = 0; a<10; a++){ >b = b + a + 1; 変数aは、for文中で0から始めて10まで1づつ増やすと書いてあります。 変数bは、初期値は0ですが代入式でb+a+1を代入しているのでa+1づつ増えるのであって、1づつ増えることはありませんし、プログラムのどこにも変数bに1づつ加算している部分はありません。なぜ、1づつ足していると思ったのでしょうか? これもちゃんと答えてくださいね。どこをどう勘違いしているか分からないとアドバイスが出来ないから聞いている事ですから。
#3です。 「bも結局0から1ずつ増やしているんですよね?」 違いますよ。 bを増やしているのではなく、計算結果をbに「代入」しているのです。(右辺の計算結果が次のbの値になる。) なので、今回の場合は 「では、b=2になることはないんですか?」 b=2になることはありません。 どうやら、数学的な「=」と代入の「=」の区別が付いていないようですね。 b=b+a+1; は、まず右辺が評価(計算)されてb+a+1が求められます。 その結果が bに「代入される」のです。なので、この場合の「=」は「b と b+a+1が等しい」という意味ではなく「b←b+a+1」(右辺の値が左辺の変数の値に入れ替わる。)というイメージです。
- zwi
- ベストアンサー率56% (730/1282)
>また、申し訳ない質問です。 >forループ1回目は、a=0でb=0なので> >a=0 でどうしてb=0になるんですか? b=b+0+1 ですよね。これでb=0なのですか? edomin2004さんの言われるとおりで、aもbもこの時点で0ですよと言う意味で書いています。aが0だからbが0になるのではなくて、この時点でaもbも0が入っています。 >実行結果の黒い画面に入力する数値はaのみですか? これも最大の勘違いだと思うのですが、このプログラムでは実行時に入力すること出来ません。 入力を受け付けるためには、出力の関数としてprintfがあるように入力の関数scanfが必要です。 scanf("%d",&a); と書いてあればコンソール(黒い画面)で変数aに数値を入力することが出来ます。これは今回関係ないので知識として覚えておいてください。 ともかく最も大きな問題は、このプログラムは1~10までの数列の和を求めるプログラムであると自分で説明しておきながら、なぜ入力が必要だと思ったのでしょうか?問題を理解していれば入力が必要だとは考えないはずですよ。 それとも代入式の左辺の変数は必ずコンソールで入力しなければいけないと誰かに教わりました?なぜ入力があると思ったか答えてもらえば、ちゃんとしたアドバイスができますので、なるべく細かく答えてください。
#3です。 「a=0 でどうしてb=0になるんですか? b=b+0+1 ですよね。これでb=0なのですか?」 この文章は、 「forループ1回目は、a=0でb=0なので…」 からきていると思うのですが、解釈が違います。 「a=0だからb=0」なのではなくて「a=0、b=0」つまり、aもbも0だということを言っています。 なぜb=0なのかというと、変数宣言時 int a,b=0; でbを0で初期化しているからですよ。 または、私の回答にある b=0; でbに0を代入しているからです。 #6さんの回答じゃないですが、もう少し「変数」と「代入」の意味を復習された方がいいみたいですね。
補足
forループ2回目は、a=1でb=1なので1+1+1で計算結果は3ですね。これもbに代入されます。b=3になります。 forループ3回目は、a=2でb=3なので2+3+1で計算結果は6ですね。これもbに代入されます。b=6になります。 とは、2・3回目も「a=1だからb=1」「a=2だからb=3」という解釈ではないですか? では、b=2になることはないんですか? bも結局0から1ずつ増やしているんですよね?
- zwi
- ベストアンサー率56% (730/1282)
前の質問に答えた事のあるzwiです。 前から思っていたのですが、未だに変数と代入式の事、プログラムが順次実行されることを理解できていないように見受けられます。 このままfor文やさらに高度なC言語の文法に進むことは混乱をさらに広げることになるので、今のうちに変数と代入式の事を十分に理解してはどうでしょうか? これまでの回答を十分に理解しないうちに先に進もうとしているため、見当違いな質問や過去の質問等同様な質問を繰り返しています。 >int a, b = 0; これは、変数bを宣言して初期値として0を与えているだけで実行順序の後の方でbに値を代入したらその値に変化します。書いてある順番を見て分かるとおりmainプログラムの最初に実行されています。 >b = b + a + 1; の左から2番目のbは何のためにあるんですか? >2番目のbは常に0ですよね。 ここで大きく勘違いしています。bの変数は1つしか無いので、1番目も2番目も同じbです。これまでの質問でも同じ様な質問を繰り返してますから変数が理解できていない証拠です。 代入式で理解すべきことは左辺が先に実行されることです。b+a+1が計算されてその結果の値がbに代入されるのが代入式です。 forループ1回目は、a=0でb=0なので0+0+1で計算結果は1ですね。これがbに代入されます。b=1になります。 forループ2回目は、a=1でb=1なので1+1+1で計算結果は3ですね。これもbに代入されます。b=3になります。 forループ3回目は、a=2でb=3なので2+3+1で計算結果は6ですね。これもbに代入されます。b=6になります。 これをforループの最後まで繰りかえてしているのです。 1+2+3+・・・を計算できているのが分かりますか? 前の例題?を見直して疑問が無いことを確認して、十分理解できてから先に進めることをお勧めします。前の問題で疑問が解消できていなかったら、その問題に戻って質問してください。
補足
また、申し訳ない質問です。 forループ1回目は、a=0でb=0なので> a=0 でどうしてb=0になるんですか? b=b+0+1 ですよね。これでb=0なのですか? 実行結果の黒い画面に入力する数値はaのみですか?
- otaks
- ベストアンサー率33% (11/33)
かなり惜しいところまで行っていると思います。 後一歩だ! ○修正前 #include <stdio.h> int main () { int a, b; for (a = 0; a <= 10; a++) { b = a + 1; printf ("b=%d\n", b); } return 0; } ○修正後 #include <stdio.h> int main () { int a, b = 0; for (a = 0; a < 10; a++) { b = b + a + 1; printf ("b=%d\n", b); } return 0; } どこを修正したかと言えば、 (1) int a, b; ↓ int a, b = 0; bになぜ0を代入するかと言うと、bをただ宣言しただけでは bの中身は不定値なので、なにが入っているか分かったもんじゃない。 ってことで0を代入して、bを0とする。 理由は(3)の中に出てきます。 (2) for (a = 0; a <= 10; a++) { ↓ for (a = 0; a < 10; a++) { a + 1の数を順番に足しているのに a<=10 では a+1 が 10+1 となり、11まで 足してしまう事になるので、「<=」を「<」に変更した。修正後では最後のa は 9 なので a+1 が 9+1 となり 10 で正しくなる。 (3) b = a + 1; ↓ b = b + a + 1; 上に出てくる(1)の変更がここに効いてくる。 一番初めにこの式が実行されるときにbに変な値が 入っていたらそれに対して + a + 1されることになってしまう・・。 説明のなかで分かりづらいところがあったら補足要求してください。 結構フィーリングで書いてますので、・・
補足
b = b + a + 1; の左から2番目のbは何のためにあるんですか? 2番目のbは常に0ですよね。 で、値が変化するメインの部分がb=のb ですよね。 もちろんb=a+1ではうまくいきませんでした。
- Oh-Orange
- ベストアンサー率63% (854/1345)
★変数の初期化って分かりますか? >b=0; とは、代入式のことですか? ↑ 『b=0』は代入式といえばそうですが『b』という変数を宣言しただけでは『値』が デタラメになっています。そこで初期化として変数『b』に『0』を入れるのです。 ・自動変数には必ず初期化してから使うのが常識となっていますので今後気をつけて下さい。 ちなみに static キーワードを付けた変数はゼロで初期化されます。 また外部変数(main関数外)に記述した変数もゼロで初期化されます。 この2つは初期化しなくても使っても構いません。 それ以外の自動変数(普通に宣言した変数)は初期化してから利用します。 初期化の値はゼロだったり、100 だったりとプログラムによって異なります。 ・今回は for() の中で『a』は 1 に初期化していますが『b』は初期化されていません。 ゼロで初期化する必要があるので『b=0;』を記述するのです。 またこの初期化は宣言と同時に記述できます。 つまり、 int main( void ) { int a, b = 0; ←ここで宣言と同時に初期化できる for ( a = 1 ; a <= 10 ; a++ ){ b += a; printf( "b=%d\n", b ); } return 0; } >bが何から始まるかを表現してるんですか? ↑ そうですね。 ゼロで初期化してゼロから始めないと上手く加算できないので『b=0;』を記述するわけです。 ・以上。
補足
そのためにはb=0;と書いて最初に空にする必要があります。あくまで最初だけです。そうしないとint b;で箱bを用意しただけでは箱bの中にボールが何個入っているかが分からないからです。> これが、変数の初期化という作業ですか? 確かにb=0を省いたらエラーが出ました。 b=0で箱が空になるということは、0でなければ空でないんですね? 0でないときもあるんですか?