• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:C言語で電卓を作成する。修正お願いします。)

C言語で電卓を作成する修正方法

このQ&Aのポイント
  • C言語で電卓を作成するプログラムの修正方法についてお知らせします。
  • 現在のプログラムでは、割り算が最初に出てくる場合に計算結果がおかしくなってしまう問題があります。
  • この問題を解決するために、int型の変数宣言を変更せずに計算結果が正しく出るようにする方法をご指導します。

質問者が選んだベストアンサー

  • ベストアンサー
  • R_Earl
  • ベストアンサー率55% (473/849)
回答No.8

ANo.2, 7です。 ANo.7ではcalc関数を修正しない方が良いと言いましたが、 ちゃんと計算できるように追加コード部分を修正してみました。 修正箇所は if((*op == '/') && (*(op + 1) == '*')){/*op='/'、op+1='*'が入った時*/  *x = (*x) * (*(x + 2));  printf("answer1 = %d\n",*x);  *(x + 2) = *x / *(x + 1) ;  printf("answer2 = %d\n",*(x + 2));  return *x; } の部分です。これを if((*op == '/') && (*(op + 1) == '*')){/*op='/'、op+1='*'が入った時*/  *x = (*x) * (*(x + 2));  printf("answer1 = %d\n",*x);  *(x + 2) = *x / *(x + 1) ;  printf("answer2 = %d\n",*(x + 2));  // return文は不要  // 以下5行が追加コード  *x = 0;  *(x + 1) = 0;  x = x + 2;  op = op + 2;  continue; } と直すと上手くいきます (インデントに全角スペースを使っているので注意して下さい)。 *x = 0や*(x + 1) = 0が必要な理由は、 calc関数内のswitch文で*x = 0が実行されている理由と同じなのですが、 何故このコードが必要なのかは分かりますか? この修正をすれば10/4*4のように、 「わり算1回、かけ算1回を行う式」には上手く対応できます。 しかし10/4/5*5*4や10/4/5*4*5のように、 「わり算が2回以上連続して続いた後にかけ算がある式」には対応できません。 これは追加コードでは、隣り合うわり算、かけ算のみを処理しているのが原因です。 例えば10/4/5*5*4では/5と*5は追加コード部分でうまく処理されるのですが、 位置が離れている/4と*4は処理されません。 これで妥協するかどうかは質問者さんに任せます。 妥協したくないなら、このコードを更に修正するか、 あるいは別の方法を取る事になります。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (7)

  • R_Earl
  • ベストアンサー率55% (473/849)
回答No.7

追加コードの部分にreturnがあります。 これではwhileループで全ての数を処理する前に calc関数を抜けてしまいます。 計算結果がおかしくなるのはそのためだと思います。 こういう面倒なことがあるので、並び替えの処理は calc関数の中でやらない方がいいと思います。 並び替えだけを行う関数を作り、main関数の中で (1) 並び替え関数 (2) calc関数(mode =1) (3) calc関数(mode =0) の順番で関数を呼び出せば良いと思いますが…。

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

掛け算を先にやったらオーバーフローの可能性があるんだけど, そこには目をつむるってのが理解できん. たとえば, int が 32ビットの環境で 1000000 / 100001 * 100001 を計算すると掛け算を先にやっても割算を先にやっても「期待した結果」にはならないはずなんだけど, そんなんでいいのか?

dezaemon1120
質問者

補足

いいです。 高精度な計算結果は求めていません。 自分が途中まで出来たのを入れます。 条件分岐を入れてみましたが、最終的な結果はおかしくなってしまいます。 下記にソースを入れます。修正箇所を教えて頂けますか? #include <stdio.h> #include <stdlib.h> /* int check_num(int *x, char *op) { int i; while(*op != '=') { for(i=0; i<10; i++) { x[i] == *(x + i); if(*(op + i) == '='){ calc(x, op , 1); } } } } */ int calc(int *x, char *op, int mode) /* x=項、op=演算子、mode=0か1で処理を分岐*/ { while (*op != '=') { /*opに'='が代入されるまで回す*/ if (mode==0) { /*mode=0の処理(mode=1で得た計算結果を最後に加算する)*/ *(x + 1) = *(x+1) + (*x); x++; /*配列に入れられた値を更新*/ op++; /*'='が出されるまでopを更新*/ } if (mode==1) { /*mode=1の処理(乗算、除算、減算を行って、計算結果を配列に入れる)*/ if((*op == '/') && (*(op + 1) == '*')) { /*op='/'、op+1='*'が入った時*/ *x = (*x) * (*(x + 2)); printf("answer1 = %d\n",*x); *(x + 2) = *x / *(x + 1) ; printf("answer2 = %d\n",*(x + 2)); return *x; } switch (*op) { /*乗算*/ case '*': *(x + 1) = (*x) * (*(x + 1)); /*例:x+1=4(x)×2(x+1)*/ *x = 0; break; /*除算*/ case '/': *(x + 1) = *x / *(x + 1); /*例:x+1=4(x)÷2(x+1)*/ *x = 0; break; /*減算*/ case '-': /*例:x+1=2×(-1)*/ *(x + 1) = *(x+1) * (-1); /*最後に加算を行うので値をマイナスにして配列に入れる*/ break; } x++; op++; } } return *x; } int main(void) { int x[10]; /* 項 */ char op[10]; /* 演算子 */ int i; while (1) { printf("式を入力してください\n"); printf("例:1*2+5=enter \n"); printf("式:"); for (i = 0; i<10; i++) { /*10項まで計算可*/ scanf("%d %c", x + i, op + i); if (*(op + i) == '=') /*op='='が代入されるまで回し続ける*/ break; } calc(x, op, 1); printf("答え:%d\n", calc(x, op, 0)); /*mode=0の処理へ移行(最後に加算をして結果を出力)*/ } /* return 0;*/ }

全文を見る
すると、全ての回答が全文表示されます。
  • TT414
  • ベストアンサー率18% (72/384)
回答No.5

>割り算と掛け算の順序を逆転させるという、 >数式解析のむずかしい技を使ってまで >int型にこだわる理由が全くわかりません。 >講師の方がこういう課題を出してきました。結構、天邪鬼なかたなので。 まともなプログラマなら少数または分数処理するものを、整数にこだわる講師はまともでありません。講師本人の知識を披露したいだけのバカです。 この手のくだらない事に頭を使わずに、学校に抗議して講師を変えてもらったほうが良いです。

全文を見る
すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.4

割り算と掛け算の順序を逆転させるという、 数式解析のむずかしい技を使ってまで int型にこだわる理由が全くわかりません。 もしよかったら、その理由を教えていただけますか?

dezaemon1120
質問者

補足

自分も正直そう思います。 しかし、講師の方がこういう課題を出してきました。結構、天邪鬼なかたなので。 ヒントでは左辺に'÷'右辺に'×'がきたら掛け算を行うということらしいですが、貼り付けてあるソースは 計算された値を一度配列に格納してから、最後に加算しているので難しいと思います。 すみませんが、お力添えをお願いします。

全文を見る
すると、全ての回答が全文表示されます。
  • phoenix343
  • ベストアンサー率15% (296/1946)
回答No.3

固定小数という考え方があります。 32bitのint型なら、左側16bitが整数部、右側16bitが小数部として扱う。 この方法ですと整数型で計算することが可能ですが、ただし有効桁数が 浮動小数のfloat、doubleに比べ小さいことに留意しましょう。。 固定小数点演算 http://www2.muroran-it.ac.jp/circle/mpc/front/old1/program/algorithm/fixedpoint/index.html

参考URL:
http://www2.muroran-it.ac.jp/circle/mpc/front/old1/program/algorithm/fixedpoint/index.html
全文を見る
すると、全ての回答が全文表示されます。
  • R_Earl
  • ベストアンサー率55% (473/849)
回答No.2

計算をする前に因数の順番を入れ換えれば良いと思います。 かけ算わり算で繋がっているところを見つけ、 その部分を、かけ算がわり算よりも左側に来るように並べかえるんです。 この前処理さえしてしまえば、 計算処理をするコードを書き換える必要はなくなります。 ただこの方法でも、1 / 2 + 1 / 2のような式には対応できません。 こういった式も処理したいなら、int型整数を2つ使って分数を表現し、 分数を使って計算処理をするという方法が考えられます。

全文を見る
すると、全ての回答が全文表示されます。
  • papapa0427
  • ベストアンサー率25% (371/1472)
回答No.1

無理です。 int型では常に少数部のカットが行われるのでどうしようもありません。言語仕様ですから、どうしても「10/4*4」の計算で常に「10」と正しい答えを出したいのならフロート型かダブル型を使用して最終的に少数部切ってください。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 電卓処理

    初めて、書き込みます。よろしくお願いします。 C言語で、電卓を作成しようとしています。 計算処理は 足し算、引き算、掛け算はint型で行い、 割り算だけは、小数点を使いたいのでfloat型を使いたい と考えています。 また、計算結果の表示は、char型の文字列として表示する。 としたとき、問題として、 float型をchar型に変換する方法がわかりません。 どなたか教えていただけないでしょうか。

  • c言語プログラム

    加減乗除および剰余の演算記号(+-* / %)と2つの整数を入力し、入力した2つの整数に対して入力した演算を施して表示するプログラムをif文ではなくswitch文を用いて作成しなさいなお、演算記号入力の際に間違った記号(+ - * / % 以外)を入力した場合は+を入力したものとして計算するものとしなさい。 ヒントで 変数としては入力演算記号に対応する変数op、入力する2つの整数に対応する変数m,n、答えに対応する変数ansを使うとよいでしょう宣言についてはopは記号なのでcharで宣言しますが、あとはすべて整数ですのでintで宣言 まずやることは演算記号以外の場合に+であることを表示するプログラムを組むと思うんですけど どうしたらいいのかわかりません力を御貸しください

  • VBA電卓について

    こんにちは、VBA初心者です。 計算機(電卓)をつくっているのですが、 小数点を入力させる仕組みにしたいのですが、 どうのようにしたら良いのでしょうか? 変数はLONGにしているので、小数点(.)はSTRINGに なってしましいうまくいきません。 お手数ですがよろしくお願いします。

  • 切捨てのできる電卓

    例えば、計算の結果が小数点第3位以下で切り捨てできるような電卓を探すには、ラウンドセレクターと小数点セレクターが付いた電卓を買えばいいのでしょうか。 2,000円までであるでしょうか。 できるだけ安いのがいいのですが、具体的なメーカーや型番をご存知なら教えて欲しいです。 よろしくお願いします。

  • c言語のプログラムです

    2つの生の整数の割り算a÷bはaからbを繰り返し引いていき、引くことが出来なくなるまでの回数を商、その時の残りを剰余をすることで、引き算だけを用いて実現することができる。このことを考慮して、while文と引き算だけを用いて割り算を実現しなさい。という問題なんですけどどのようにプログラムを作っていいやらわかりません 一様ヒントはあります ・変数としては、入力する二つの整数に対応する変数m,n、商に対応する変数q、剰余に対応する変数rを使うとよいでしょう。すべて整数ですのでintで宣言する。 皆さんのご協力お願いします

  • C言語で電卓を作成する。

    C言語を用いて三項まで計算できる電卓を作りたいのですが、どうも上手くいきません。 四則演算(+、-、×、÷)の優先順位を用いたプログラミング方法が分かりません。 以下に自分で作成したソースを添付します。 このソースに修正や追加して3項までの四則演算できるプログラミングを教えていただけますか? 宜しくお願いします。 #include <stdio.h> int main(void) { int answer; /*答え*/ int x,y,z; /*x=第一項,y=第二項,第三項*/ char op1,op2; /*演算子1、演算子2*/ while(1){ printf("式を入力してください\n"); printf("式:"); scanf("%d %c %d %c %d" ,&x,&op1,&y,&op2,&z); if((op1=='+'|'-'|'*'|'/') && (op2=='+'|'-'|'*'|'/')){ switch(op2){ case '+': answer=y+z; break; case '-': answer=y-z; break; case '*': answer=y*z; break; case '/': if(z==0){ printf("ERROR\n"); return 0; } answer=y/z; break; default: printf("ERROR\n"); return 0; } switch(op1){ case '+': answer=x+answer; break; case '-': answer=x-answer; break; case '*': answer=x*answer; break; case '/': if(y==0){ printf("ERROR\n"); return 0; } answer=x/answer; break; default: printf("ERROR\n"); return 0; } printf("答え:%d\n",answer); } else { switch(op1){ case '+': answer=x+y; break; case '-': answer=x-y; break; case '*': answer=x*y; break; case '/': if(y==0){ printf("ERROR\n"); return 0; } answer=x/y; break; default: printf("ERROR\n"); return 0; } printf("答え:%d\n",answer); } } } 左辺に×、÷が来ても優先的に計算されません。

  • 関数電卓での角度を用いた計算

    SHARPの関数電卓(EL-5120)を使用しているのですが、例えばsin○○°○○′○○″等を電卓上で表示するにはどうしたらいいのでしょうか?また、それを用いた計算方法(掛算、割り算)の方法を教えて下さい。

  • C言語の電卓におけるincludeについて

    C言語の電卓におけるincludeについて C言語の電卓におけるincludeについて質問です。 プログラミング言語C第2版 ANSI規格準拠 B.W.カーニハン・D.M.リッチー著 質問1. 4章にある電卓プログラムですが、getch.cがcalc.hをincludeしないのはなぜですか? 解説よろしくお願いします calc.h #difine NUMBER '0' main.c #include <stdio.h> #include <stdlib.h> #include "calc.h" #difine MAXOP 100 getop.c #include <stdio.h> #include <ctype.h> #include "calc.h" stack.c #include <stdio.h> #include "calc.h" #difine MAXVAL 100 getch.c #include <stdio.h> 質問2. 第4章までしか読んでいませんが、「関数で返さない値はゴミ(garbage)になる」と書いていました。 関数で返さない値は、関数から抜けると消えるものと思っていたので驚きました。 関数で返さない値の後処理はどうすればいいのですか? 質問3. 外部変数と静的変数の違いは? ―メモ― 局所変数 自動変数     main内の変数     int x;                          static int x; 永久的なメモリが与えられることを意味する 外部変数          main外の変数     static int x; 静的変数          関数内の変数     static int x; レジスタ変数        変数をレジスタに置く register int x; 以上、有識者の方、教えてくださいmm

  • 電卓の使い方について、例 1,000×20%=200-=800はぜですか?

    こんにちは、みなさん。 電卓の使い方を伺いたいのですが、 Q1例 1,000×20%=200-=800になるのは なぜでしょうか? 1,000×20%=200を押した後にマイナス(-) キーを押すと 前に計算した、1,000-200を計算してくれます。 使えれば、大変良い機能なのですが、原理を知りたいです。 Q2 RM(リターンメモリー)した数字は普通にその後、足し算、引き算、掛け算、割り算が行えるのですか? 例 100(M+)100(M+)(MR)200 ←この200に対して、普通に足し算、引き算、掛け算、割り算が行えるのですか? 以上2点、ご存知の方いらっしゃいましたら、教えて下さい。よろしくお願い致します。

  • C#で電卓のプログラムを組んでいるのですが

    質問です。 電卓のプログラムにおいて、小数点のボタンがありますよね。それを重複して入力されないようにしたいのですが。何か良い方法はないでしょうか? よろしくお願い致します。