- ベストアンサー
C言語の四則計算プログラムを作成する留意点
- 選択型、反復型、関数scanfを使用して四則計算を行うプログラムを作成する。演算の種類と数値を入力し、結果を表示する。
- プログラムの中で、変数の宣言と初期化が行われていないため、予期しない動作が発生する可能性がある。
- 演算の種類が4未満の場合、数値の入力と計算結果の表示を繰り返す。それ以外の場合は計算ができないとエラーメッセージを表示する。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
ここまで書けるのでしたら、まず、自分の頭で、各変数の値がどうなっているか、どのようにプログラムが流れていくかのシミュレートをしましょう。 c = a + b; d = a - b; e = a * b; f = a / b; 冒頭近くの、この演算。何をしていますか?ここまで終わった時、登場している各変数の値は何ですか? ループの始まり。 while(m=1){ これ、C言語を始めたばかりの人が良くやるミスが含まれます。(往々にして、ここに打つ時に間違えることもあります。もしそうだったらごめんなさい。) ここに書いてあるとおりだとすると、このループは無限ループとなります。何故か解りますか? C言語の構文としては合っています。でも、おそらくやりたいことは違います。という初心者にとっていやらしいエラーです。 switch (n<=4){ これも、構文としては合っています。でも、きっとやりたいことは違います。 switch文の括弧の中の式の結果は、case文の後ろの数字と比較され、同じ数値の所に分岐します。では、()内の式の結果が何かわかりますか? C言語においては、代入・比較を含む全ての式に、結果があります。 というわけで、式を受け入れるとこには、大概の場合においてどんな式を書くことも出来ます。比較のつもりで代入しても、構文的には何ら問題はありません。これは、時としてテクニックとなりますが・・・普通は間違いを誘発します(苦笑) case 1: printf("整数を入力してください:"); scanf("%d",&b); printf("%d + %d = %d \n",a,b,c); break; case文の中全てに当てはまります。printfが実行される時、a,b,cの各変数に入っている数字を考えてください。特にcには何が入っていますか? なにせ、bを入力した直後のprintf文です。まさか、cに計算結果は入っていませんよね。 while(m=1) { で表記されるループが二重になっていますが、意図は何ですか? ここまで、ちゃんと直したとします。 printf("計算を終了しますか、それとも他の計算を行いますか?:"); printf("0:計算終了,1:他の計算を行う:"); scanf("%d",&m); 末尾近くのこの文は、いつ実行されますか?プログラムの動きを頭で追いながら、よく考えましょう。これが実行されないと、計算が終了できません。 これもちゃんと直したとします。 ここからは、プログラムの仕様には書いていませんが、普通常識としてそうだろうなという指摘です。 「他の計算を行う」を指定した時、次に実行されるscanfはどの行の物ですか?他の計算というのは、第一引数と演算子が同じで第二引数だけ違う計算をすることなのかな? ここまで直せば、プログラムは、仕様通りの動きをするでしょう。 最後です。 各case文は、全てが printf("整数を入力してください:"); scanf("%d",&b); の二行で始まります。 このように、カット&ペーストでプログラムを入力したくなったら、流れを疑いましょう。共通化できませんか?場所を変えるだけで、一つで済みませんか? 本来は、この質問は、カット&ペーストをして、中身を少しだけチョコチョコいじるという時に発生します。関数を学べば、理解できますが・・・ここまではまだ進んでいないかな? 無駄な行という意味では、もう一つ。何故、四則演算の各々の計算式用に結果変数を用意したのでしょう。このロジックであれば、同じ変数でも良いはずです。(足し算と引き算の結果を同時に使うことはありませんよね。) まぁ、答えすれすれという感じではありますが、一応、考えいただく余地を残しておきました。 後は、がんばって期限に間に合わせてくださいね。
その他の回答 (4)
- kmee
- ベストアンサー率55% (1857/3366)
> short a,b,m,n; > scanf("%d",&n); > scanf("%d",&a); > scanf("%d",&b); > scanf("%d",&m); これは、sizeof(short) == sizeof(int)の環境でないと期待通りに動作しません。 scanfの書式文字列にある%~と、それに対応する引数の型は一致させる必要があります。 ** C言語の仕様上、コンパイルエラーにはなりません ** 。ですので、プログラマ側で正しく記述する必要があります。 # 一部コンパイラでは、このプログラムのように直接記述してある場合に限って、書式と引数が一致しない、という「警告」を出すものはあります。 # ただ、詳しい警告を出す設定が必要です。また、警告はエラーでは無いので、コンパイル自体は正常終了します(警告をエラーとして扱う設定をしていない場合) scanfのマニュアルで、書式のところをよく読んで ・ short a,b,m,n ;をそのままにして、"%d"ではなく正しい書式に ・ "%d"をそのままにして、 short a,b,m,n ;ではなく、正しい型に 変更してください。 # このプログラムなら、shortを使う意図がまったくわかりません。"%d"をそのまま、型を変えるのが妥当と思います。 > while(m=1){ > switch (n<=4){ これらと同様、「言語仕様としては正しく、コンパイルもできるのに、実際の動作が期待通りでない」という、やっかいな間違いです。 他のツッコミとして > 選択型、反復型 ってなに? # この並びなら、「選択構文」「反復構文」の意味だろうけど。 > main() main関数の定義にこんな書き方をしている参考書は捨てましょう。 大学の教科書なら「昔から使い回していて、新しいのにするつもりが無いんだな」と思いましょう。 > long c,d,e,f; これもlongを使う意図がわかりません。 4つ用意することも、意図はわかりますが、このプログラムでは意味はありません。 このプログラム限定で言えば、そもそも、変数を用意する必要もありません。 > printf("整数を入力してください:"); > scanf("%d",&b); 間違いではないですが、同じ処理を何度も書くのは「間違い」のもとです。 なにより、「面倒臭い」です。(コピペで簡単にできる?いや、そのコピペ自体が面倒臭い) ・nを入力 ・nが正しい(1≦n≦4)か判定、正しい時のみ続きを処理 ・a,bを入力 ・nによって指定された計算と出力 とすれば、同じ処理が一つにまとまります。 # 「面倒臭いからなんとか楽できないか?そのための努力ならなんでもする」 # と考えるのが、プログラミング上達のコツ、だと私は考えます。
- black2005
- ベストアンサー率32% (1968/6046)
何で素直に1~4の順に処理しないの? コーディングでは3から処理しようとしてるでしょ。 それが間違いの原因。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> 以下のプログラムはこのことを留意してプログラムをつくりました。どこがおかしいのでしょうか。 まるでデタラメすね。 > #include<stdio.h> > main() { > short a,b,m,n; > long c,d,e,f; > > c = a + b; > d = a - b; > e = a * b; > f = a / b; a,b に入力もしてない段階でc,d,e,fを求めても意味ないでしょ。
- unacyo
- ベストアンサー率51% (35/68)
計算結果はどうなったんでしょう?おそらく、意味不明な値になってますよね? とりあえず、あれ?っと思った部分。 まず1つ目、switch()へ渡す値がおかしいです。 switch()は値をcaseの値と同じかどうか判断するので、switch()内で評価させてはいけません。 きっと、+の計算しかできていないのでは? 2つ目。なんでa,bの値入力前にc,d,e,fを計算しているんでしょう? aとbに値が入っていない(というより、不定の値が入ってる)状態でc,d,e,fを計算しちゃってるので、入力した値と違う結果になりますよね? scanf()でbを入力したあとで、c,d,e,fの計算をしないとダメです。 3つ目。計算が終了できませんよね、これ? 計算を終了するかどうか問い合わせるならば、while( m == 1 ){ /* ここでやるべきですよ? */ } 4つ目。while( m == 1 )がなんで2つあるんでしょうか? この内容であれば、1つあれば十分のはずですが。