- ベストアンサー
入力した数値を倍々するプログラム
整数を1つ読み込み、それを倍々しながら10回書き出すプログラムを作成しています例えば、実行結果に3と入力すると、3、6、12、24、48、96、192・・・と書き出すものです。 for文かwhile文を使うことを指定されているんですが、どちらを使ったら良いでしょうか? for(A;B;C)のCの部分には、実行する式が入るんですよね? ただ、入れてはいけないものはありますか? 今まで、a++、a--しか見たことがないので、実行する式を入れてもエラーがでてしまいます。
- みんなの回答 (14)
- 専門家の回答
質問者が選んだベストアンサー
★プログラムの基本は上から下へ順に処理。 >3と入力した場合、a*=2が後に来ると、最初に3が表示されるのは、どうしてですか? ↑ 『a *= 2;』よりも表示命令の『printf( "%d ", a );』が先に処理されるからです。 別の質問で誰かが上から下へ処理されるとアドバイスしていませんでしたか? ここがポイントですよ。 ・C 言語のプログラムは基本的に上から下へ流れるように処理されます。 でも if、else、switch文で処理の分岐を行うとジャンプして飛んだ先から処理され、 for、while、do-while文の繰り返しでは、処理される場所が繰り返しの最初の場所に 戻って処理されたりします。 この処理の流れが重要です。 ・今回の場合は (1)『a *= 2』→『printf( "%d ", a );』の順 scanf( "%d", &a ); while ( n-- > 0 ){ a *= 2; printf( "%d ", a ); } (2)『printf( "%d ", a );』→『a *= 2』の順 scanf( "%d", &a ); while ( n-- > 0 ){ printf( "%d ", a ); a *= 2; } ・上記の2つは上から下への順に処理される事から表示結果に微妙な違いが出ます。 (1)…最初 a=3 ですので a *= 2 の処理を行うと a=6 となります。 この後に printf 文で a 変数の内容を表示するため実行結果が 6、12、24、48、96…と表示されるのです。 (2)…最初 a=3 ですが先に printf 文で a 変数の内容を表示します。 その後に a *= 2 の処理を行うため実行結果が 3、6、12、24、48、96…と表示されるのです。 つまり 先に表示してから掛け算すると 3 から始まり、 先に掛け算してから表示すると 6 から始まる 事になります。これは処理順が上から下の方向で処理されるからなのです。 よって 『a *= 2』 と 『printf( "%d ", a );』 の行を入れ替えると処理順が変るから表示も変るのです。 >a*=2とは関係がないんですか? ↑ 関係があります。大有りです。 もし『a *= 2』の記述をしなければ、ずっと a=3 のまま 10 回表示されます。 『a *= 2』の記述があるために行を入れ替えると表示→掛け算や、掛け算→表示の 違いから実行結果も微妙に異なってくるのです。 ・何度に言いますが『プログラムは上から下への順に処理』されます。 ここをきっちりと覚えて下さい。 紹介: ・今後の為に用意した方がいい本を紹介します。 (1)http://www.amazon.co.jp/dp/4797325631/→『新C言語入門 スーパービギナー編』 (2)http://www.amazon.co.jp/dp/4797325615/→『新C言語入門 ビギナー編』 (3)http://www.amazon.co.jp/dp/4797325623/→『新・C言語入門 シニア編』 この本のうち(1)を先に読んでみた方がいいです。 ・(1)は普通のC言語の本(教科書も含む)を読んでもイマイチ理解できない初心者の中の 初心者さん用に書き下ろされたという位置づけの本です。 この本には『プログラムとは』、『変数って何?』などの基本の基本が書かれています。 余談: ・昔、私が学生だった頃に C 言語の授業がありました。 でも 9 割近くが実習で意味のない授業でした。 お陰で C 言語は大嫌いになった。→懐かしい。 ・その後、数年の月日が流れ会社でプログラムを組むことになりました。 それも C 言語を使ってです。 ほとんど理解できていなかった C 言語でプログラムをするか!と不安。 でも運が良いのか会社に上記の本のシリーズ(2)がありました。 ・つまり、むかし私は上記の本のシリーズに出会った訳。 この本のお陰でわずか2ヵ月で難しいとイメージしていたポインタとか構造体の使い方などが 理解できました。そこで本屋でこのシリーズを買いそろえました。 買ったのはビギナー編、シニア編、応用編です。昔はスーパービギナー編はありませんでした。 ついでに私が買った本は今では古すぎで売っていません。→もう 10 年以上前なので。 でもほぼ同じ内容で新しく改訂した本として上記の本が買えます。 さらにスーパービギナー編が加わってね。→去年その存在を知って本屋でペラペラと見た。 ・もう C 言語を知っているのでスーパービギナー編は買いませんが、むかしこの本があったら 買っただろうなと思いました。今思うと懐かしい C 言語嫌いの学生時代。 ・以上。余談と一緒に『スーパービギナー編』の本をお勧めします。
その他の回答 (13)
- 1839cc
- ベストアンサー率54% (12/22)
プログラミング言語を、なにやら摩訶不思議な記号の並びと考えているのではないですか? プログラミング言語など、ただの指示書です。 多くの指示書は、特に指定がない限り、普通は上から順に実行していくものです(順次処理って習いませんでしたか?)。 あなたに指示書を与えます。 手順どおりに実行してみてください。 手順1: 任意の値を A とせよ。 手順2: 以下の手順を10回繰り返せ。 手順2-1: A の値をノートに書き出せ。 手順2-2: 二倍した値で A を置き換えよ。 どうでしょう。 ノートには、期待通りの結果が書かれたはずです。 これをあなたは以下のように書き換えたのです。 手順1: 任意の値を A とせよ。 手順2: 以下の手順を10回繰り返せ。 手順2-1: 二倍した値で A を置き換えよ。 手順2-2: A の値をノートに書き出せ。 さて、実行してみてください。 ノートにはどんな結果が書かれていますか? この指示書は、前述のコードを日本語で書いただけのものです。
お礼
手順を変えて試してみます。
- Oh-Orange
- ベストアンサー率63% (854/1345)
★前回、前々回の補足の意味が知りたいです。 >a *= 2;から順序を逆にしたら、実行結果は入力した数値*1の値が表示されなくなりました。 >どうしてですか? ↑ 何が表示されなくなった? 『数値*1』とは? >3と入力すると、「6、12、24、48・・・」と表示されます。 ↑ 正常に動いていますけど。 何か問題があるのか? ・質問では >3と入力すると、3、6、12、24、48、96、192・・・と書き出すものです。 ↑ となっています。 結果が異なるという事を聞きたいのかな? 『a *= 2;』を先に計算した後に『printf("%d ",a);』と表示しているので 『6、12、24、48・・・』と表示されて正しいですけど。 ↑ 行を入れ替えたのでしょ。自分でさ。 ・結局、何が表示されなくなったのか?『数値*1』とは?何? 一体何をアドバイスして欲しいのですか? その他: >C言語は好きでも嫌いでもありませんが、大学の授業で必須でして、 >去年単位を落としたので、再履修という形で履修します。 >それでやっているというのが大きいです。 ↑ やっぱね。 C言語の教科書とか読んでいる?→読んでも良く分からないんでしょう。 授業の必須でやっているようですけど、もう単位を落としたくないなら教科書や 教科書以外に本屋で C 言語の分かりやすい解説がある本を1冊用意した方が良いと思います。 ・前の質問でかなり苦戦していて宣言、代入、初期化などの基本が良く分かっていないようです。 教科書以外に用意した方が良いです。本当に。2000円~3000円クラスでも分かりやすいのあるから。 ・あとこの質問でまだしっくり来ないことがあるなら詳しい補足をお願いします。 回答 No.10 の『回答への補足』で >実行結果は入力した数値*1の値が表示されなくなりました。 >どうしてですか? ↑ これってどういう意味ですか? 回答 No.11 でそれを一番補足して欲しかった。 なので今回もまた同じ補足要求です。 何が知りたいのですか? ・以上。私には『数値*1』が補足してくれないと分からんよ。何?
補足
printf("%d ", a);とa*=2;の順序を入れ替えても実行結果は変わらないと勘違いしていました。実行結果に3と入力した場合、a*=2が後に来ると、最初に3が表示されるのは、どうしてですか? a*=2とは関係がないんですか? 以降6は a=3*2 で6になっているんですよね?
- Oh-Orange
- ベストアンサー率63% (854/1345)
★えっ。表示されない? >実行結果は入力した数値*1の値が表示されなくなりました。 ↑ これはどんな意味? >a *= 2; >printf("%d ", a); >と >printf("%d ", a); >a *= 2; ↑ 行を入れ替えたのか? ・行を入れ替えても 先に2倍されて表示されるか、 次から2倍されて表示されるか の違いだけで表示はされると思いますけど。 ・ソースを貼り付けて下さい。 そうしないと分かりませんけど。 あと全く表示されなくなったのかも補足して。 ・それから C 言語(プログラミング)は好きですか? 今後のアドバイスの基準としたいので教えてくれますか? もし、嫌々で C 言語を行っているのなら勉強方法を少し変える必要がありますよ。 ・それではソースなどの補足を待っています。
補足
ソースは #include <stdio.h> int main(void) {int a, n = 10; printf("aを入力 > "); scanf("%d", &a); while (n--) { a *= 2; printf("%d ", a);} return 0;} で、3と入力すると、「6、12、24、48・・・」と表示されます。 C言語は好きでも嫌いでもありませんが、大学の授業で必須でして、去年単位を落としたので、再履修という形で履修します。それでやっているというのが大きいです。
- Oh-Orange
- ベストアンサー率63% (854/1345)
★まだ習っていないようだね。 >a *= 2;は初めて見たんですが、どういったときに使えるんですか? >*の後に数値がありませんが、a*何なんですか? ↑ 『a *= 2;』とは複合代入演算子というものです。 ↑ これを普通の代入演算子として記述しなおすと 『a = a * 2;』 となります。つまり『a * 2』の部分を省略して同じ変数への加算、減算、乗算、除算などは 『a *= 2;』 という複合代入演算子での記述が C 言語では出来るのです。 ・他にも次のようなものが用意されています。 (1)『a = a + 数値;』は『a += 数値;』と同じ (2)『a = a - 数値;』は『a -= 数値;』と同じ (3)『a = a * 数値;』は『a *= 数値;』と同じ (4)『a = a / 数値;』は『a /= 数値;』と同じ (5)『a = a % 数値;』は『a %= 数値;』と同じ (6)『a = a & 数値;』は『a &= 数値;』と同じ (7)『a = a | 数値;』は『a |= 数値;』と同じ (8)『a = a ^ 数値;』は『a ^= 数値;』と同じ (9)『a = a << 数値;』は『a <<= 数値;』と同じ (10)『a = a >> 数値;』は『a >>= 数値;』と同じ 上記のうち(1)~(5)は良く知っている四則演算による複合代入です。 そして(6)~(8)はビット演算による複合代入であり、 さらに(9)(10)はシフト演算による複合代入となります。 ※(6)~(10)はまだこれから習うと思いますが複合代入として用意されています。 詳しくは下の『参考文献』を読んでみてね。 ・あと上記の(1)~(10)の『数値』となっている部分は『変数』も記述できます。 よって int a = 100; int b = 200; a += b; という場合は a = a + b; と同じ処理となり a=100 と b=200 を加算して a=300 が代入されます。 ・以上。 参考文献: (1)http://members2.jcom.home.ne.jp/take_1118/java15.html (2)http://www5c.biglobe.ne.jp/~ecb/java/05_03.html (3)http://gihyo.jp/dev/serial/01/c-programming-introduction/0010 ※(1)(2)は Java 言語のようですが複合演算子とかは C 言語と同じ意味なので紹介。 ※(3)は C 言語による解説です。
補足
a *= 2; printf("%d ", a); とprintf("%d ", a); a *= 2;から順序を逆にしたら、実行結果は入力した数値*1の値が表示されなくなりました。 どうしてですか?
- Oh-Orange
- ベストアンサー率63% (854/1345)
★アドバイス >具体的には、10は変数 n の初期値なんですか? ↑ そうなるね。 質問では10回書き出すプログラムとなっているので『10』です。 >n--ということは、10から1ずつ減らしているんですか? ↑ そうだね。 カウント・ダウンです。 for ( n = 0 ; n < 10 ; n++ ) の場合はカウント・アップですけど減らして数えて ゼロになったら while() 文を抜けるというやり方でも指定回数のループを組めます。 >どうイメージすればいいですか? ↑ まずソースを次のように書き直しました。 while ( n-- > 0 ){ printf( "%d ", a ); a *= 2; } こうすると while() の条件式として理解できますか? イメージとはこのようにして見るのが良いですよ。 あと n=10; なので 1回目…n=10⇒while( 10 > 0 )⇒条件式は『真』⇒またループする 2回目…n=9⇒while( 9 > 0 )⇒条件式は『真』⇒またループする 3回目…n=8⇒while( 8 > 0 )⇒条件式は『真』⇒またループする 4回目…n=7⇒while( 7 > 0 )⇒条件式は『真』⇒またループする 5回目…n=6⇒while( 6 > 0 )⇒条件式は『真』⇒またループする 6回目…n=5⇒while( 5 > 0 )⇒条件式は『真』⇒またループする 7回目…n=4⇒while( 4 > 0 )⇒条件式は『真』⇒またループする 8回目…n=3⇒while( 3 > 0 )⇒条件式は『真』⇒またループする 9回目…n=2⇒while( 2 > 0 )⇒条件式は『真』⇒またループする 10回目…n=1⇒while( 1 > 0 )⇒条件式は『真』⇒またループする 11回目…n=0⇒while( 0 > 0 )⇒条件式は『偽』⇒もうループしない ↑ このように動作します。 ・以上。
補足
a *= 2;は初めて見たんですが、どういったときに使えるんですか? *の後に数値がありませんが、a*何なんですか?
- Oh-Orange
- ベストアンサー率63% (854/1345)
★いろいろとアドバイスをしてみます。 >for文かwhile文を使うことを指定されているんですが、どちらを使ったら良いでしょうか? ↑ これはどちらでもお好みで構いません。 直感的に分かりやすいとか、 直感的に見やすいなどで使い分ける。 ・例えば『初期値』、『繰り返し条件』、『増減分』が3つ揃っていて増減分が a++、a-- の 単純なカウンタの場合は for()文を利用します。→『for ( i = 0 ; i < 10 ; i++ ){ … }』など while() 文はこれより前に初期化を設定した方が見やすい場合や、無限ループ、最低1回は ループ処理される do{ … } while(式); を組みたい場合に使います。 例えば char *dest = buff; ←コピー先領域 char *tail = string; ←コピー文字列 // string を buff にコピーする処理 while ( (*dest++ = *tail++) != '\0' ){ ; } ↑ こんな場合は for() 文を使うよりは while() 文の方が見やすいのでお勧め。 ・ちなみに上と同じ処理を for() 文で記述すると char *dest; ←コピー先領域 char *tail; ←コピー文字列 // string を buff にコピーする処理 for ( dest = buff, tail = string ; (*dest++ = *tail++) != '\0' ; ){ ; } とか // string を buff にコピーする処理 for ( dest = buff, tail = string ; *tail != '\0' ; ){ *dest++ = *tail++; } とか // string を buff にコピーする処理 for ( dest = buff, tail = string ; *tail != '\0' ; *dest++ = *tail++ ){ ; } になります。 どれもちょっと見づらい気がしますね。私の好みですが…。 >for(A;B;C)のCの部分には、実行する式が入るんですよね? >ただ、入れてはいけないものはありますか? ↑ if、else、goto などの制御命令やそれを使って定義されたマクロ関数などはエラーとなる。 基本的に for() 文は while() 文に初期化式と増減分(再初期化式)を記述できるように しただけで while() と同じ機能を持つ。また for( 式1 ; 式2 ; 式3 ) の3つの式は それぞれ独立しているので省略したり、printf() 関数などの記述さえも行える。 ・つまりは int i = 5; for ( printf("最初\n") ; --i >= 0 ; printf("中間\n") ){ printf( "処理中:" ); } と記述することも出来ます。ちなみに実行すると ------------ 最初 処理中:中間 処理中:中間 処理中:中間 処理中:中間 処理中:中間 ------------ と画面に表示されます。 ・あと for() 文の式1、式2、式3 のすべてを省略して for( ; ; ){ … } とすると無限ループを 構成できます。これは while ( 1 ){ … } と同じ効果です。でも for() 文を使って無限ループに すると変てこな警告メッセージが出ないですみます。なので無限ループを組むなら for() 文を お勧めします。 それでは本題: >整数を1つ読み込み、それを倍々しながら10回書き出すプログラムを作成しています >例えば、実行結果に3と入力すると、3、6、12、24、48、96、192・・・と書き出すものです。 ↑ どこまで出来たのかソースを見たいです。 それと読んでくれたのならコメントを下さい。 いつもないね。何で?ちょっと寂しいな~。 コメントだから感想とか、補足とかで良いよ。 ・下に for()、while() の2タイプでサンプル(回答)を載せておきます。 サンプル1: int num, i; // 入力 scanf( "%d", &num ); // 倍々にして10回書き出す for ( i = 1 ; i <= 10 ; i++ ){ printf( "%d回目 num=%d\n", i, num ); num = num * 2; } サンプル2: int num, i = 1; // 入力 scanf( "%d", &num ); // 倍々にして10回書き出す while ( i <= 10 ){ printf( "%d回目 num=%d\n", i, num ); num = num * 2; i++; } その他: ・上記のサンプルは見やすいように全角空白でインデントしています。 コンパイルする時には、エディタで『全角空白文字』→『タブ文字』に一括変換してから 実行して下さい。 ・サンプル1は for() 文を使ってサンプル2は while() 文を使って書いてみました。 どちらでも同じ処理結果になります。 私はサンプル1の for() 文の方が見やすいと思いますけど。 jlnh さんはどう思う。感想をちょうだい。 ・以上。下の『参考URL』もどうぞ。
補足
すみません。実行できました。全角のスペースが含まれていたので、それを省いたら実行できました。 ただ、ソース #include <stdio.h> int main(void) {int a, n = 10; printf("aを入力 > "); scanf("%d", &a); while (n--) { printf("%d ", a); a *= 2; }return 0;} で分からないところがあります。 一言で言えば、どうしてこのソースでうまくいくのかということなんですが、具体的には、10は変数nの初期値なんですか? n--ということは、10から1ずつ減らしているんですか? どうイメージすればいいですか?
- aris-wiz
- ベストアンサー率38% (96/252)
>実行する式を入れてもエラーがでてしまいます。 ・何をどう入れて。 ・どのようなエラーが起こったのか。 あなたにはこの2つがわかっていても、 回答者にはまずこれがわかりません。 これを明確にしなければ、あなたの質問に対する明確な回答を 答えることは難しいです。 >for文かwhile文を使うことを指定されているんですが、 >どちらを使ったら良いでしょうか? どちらでも、自分のわかりやすい方でいいと思います。 >for(A;B;C)のCの部分には、実行する式が入るんですよね? >ただ、入れてはいけないものはありますか? C言語的に言うと再初期化式というものが入ります。 この式の後に「;」を含めることはできません
- tatsu99
- ベストアンサー率52% (391/751)
#3のかたは、見やすくするためのわざわざ全角で空白を記述しています。 したがって、それをこぴーして、張り付けただけでは、コンパイルエラー になってしまいます。 #3のかたのソースを、全角の空白を半角の空白にしてからコンパイルしないといけません。 #3のかたのソースを全角の空白を半角の空白にしたものを、ここに記述しますので、これを実行して下さい。 うまくいったら、感謝の言葉は、#3のかたに返してあげて下さい。 -------------------------------------- #include <stdio.h> int main(void) { int a, n = 10; printf("aを入力 > "); scanf("%d", &a); while (n--) { printf("%d ", a); a *= 2; } return 0; }
- asuncion
- ベストアンサー率33% (2127/6290)
No.3の回答をした者です。 > このコードで実行した結果、エラーがでてしまいます。 「どんな」エラーが出ましたか? 具体的な状況を知らせていただかないと、先へ進めません。
- zwi
- ベストアンサー率56% (730/1282)
毎度おなじみのzwiです。 「エラーが出ます」だけだと情報が不十分ですので、出ているエラーを正確に報告してくださいね。画面に出ている情報を出来るだけ詳しくお願いします。 ちょっとアドバイス。 いきなりプログラム全体を作るより、例えばscanfだけを実験するプログラムを作って動作を確認してから疑問があれば質問するようにしたほうが良いですよ。このままだと自力でなかなか先に進めない、新しい機能ごとに行き詰ってしまいます。 せっかくすぐ試せる環境があるのですから、使わないのは勿体無いです。 本で調べる→その機能を徹底的に試してみる→本で再確認→疑問が残ればここで質問。
- 1
- 2
お礼
分かりました。とりあえず締め切らせてもらいます。