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);
}
}
}
左辺に×、÷が来ても優先的に計算されません。
No.4ベストアンサー
- 回答日時:
どこまでの道具が使えるのかどうかにはよりますが、雰囲気からすれば、2項の「電卓」はコードがあるようですね。
これを、3項に拡張する場合、だらだらとコードを付け加えてゆくよりは、今ある部分を機能的に独立させる方が見通しは良くなります。
たとえば、こんな感じ。
int calc2term(int a, char op, int b)
{
// a op b の値を返す
}
int comp_op(char op1, char op2)
{
// op1 と op2 優先順序を確認する
// op1 が優先なら、-1 を
// op2 が優先なら、1 を
// 優先順序が同じなら 0 を返す。
}
int main()
{
int answer;
// ここまでで、z, y,z op1, op2 が入力されたものとする
if (comp_op(op1, op2) == 1) // 特別扱いするのは、op2 のほうが優先順序が高いときだけ
{
answer = calc2term(y, op2, z);
answer = calc2term(x, op1, answer);
// op2 のほうが優先順位が高いので x op1 (y op2 z) を計算する。
}
else // それ以外の時は、op1 op2 の優先順序が同じ時も含めて、左から順に計算すればいい
{
answer = calc2term(x, op1, y);
answer = clac2term(answer, op2, z);
// (x op1 y) op2 z を計算する
}
// answer の値を表示する。
return 0;
}
この回答への補足
回答ありがとうございます。
3項だけの計算で出来ました。
さらに質問で申し訳ありませんが、以下のプログラムを基に3項だけの計算を2項以上10項以下で可能にしたいのですが、アドバイスをお願いします。
以下に参考のプログラムを貼り付けます。
#include <stdio.h>
#include <stdlib.h>
int calc(int a, int b, int op)/*計算を行ってる関数*/
{
int answer;
switch(op){
case '+':
answer=a+b;
break;
case '-':
answer=a-b;
break;
case '*':
answer=a*b;
break;
case '/':
if(b==0){
printf("0で割ることは出来ません\n");
exit(1);
}
answer=a/b;
break;
default:
printf("ERROR\n");
exit(1);
}
return answer;
}
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=='+') || (op1=='-')) && ((op2=='*') || (op2=='/'))) /*右辺と左辺の計算の優先順位の判断*/
{
answer = calc(y, z, op2);/*右辺を初めに計算*/
answer = calc(x, answer, op1);/*右辺の計算後に左辺を計算*/
printf("答え:%d\n",answer);
}
else
{
answer = calc(x, y, op1);/*左辺を計算*/
answer = calc(answer, z, op2);/*右辺を計算*/
printf("答え:%d\n",answer);
}
}
return 0;
}
No.5
- 回答日時:
No.4 です。
残念ながら、この方針では3項限定でしか処理ができません。
まず、入力からして、数字が3つであることを前提にしていますね。
これ以上項数を増やすためには、「繰り返し」または、「再帰」という仕掛けを導入する必要があります。
※その意味では、No.4 の回答も、柔軟性を欠くものです。
なので、知るべき事は多く、簡単なアドバイスでどうにかなるというレベルではない気がします。
とりあえず、一度配列に読み込んで、乗除算の部分だけ前もって計算して別の配列に移し、最後に加減の計算をするという方針で作ってはみました。
紙の上に、式を書いて何をやっているか追いかけてみれば、流れはわかると思います。
あと、入力の最後は、= です。 1+2*3+4= とか。
int main()
{
int num[10];
char op[10];
int numCount;
int num_wk[10];
char op_wk[10];
int wkCount;
int i;
int j;
int result;
int wk;
int leftTerm;
int rightTerm;
op[0] = '+';
scanf("%d", &num[0]);
for(i = 1; i < 10; i++)
{
scanf("%c", &op[i]);
if (op[i] == '=') break;
scanf("%d", &num[i]);
}
for(j = 0; j < i; j++)
printf("%c %d\n", op[j], num[j]);
// 計算開始
numCount = wkCount = 0;
while(1)
{
if ((op[numCount + 1] != '*') && (op[numCount + 1] != '/'))
{ // 優先順序を意識する必要は無い
op_wk[wkCount] = op[numCount];
num_wk[wkCount] = num[numCount];
numCount++;
wkCount++;
}
else
{
// 優先順序を意識する(乗除の部分を項として計算する)
op_wk[wkCount] = op[numCount]; // 項の前の符号を最初に保持
wk = num[numCount];
numCount++;
while((op[numCount] == '*') || (op[numCount] == '/')) // 次の項が始まるまで
{
wk = calc(wk, num[numCount], op[numCount]);
numCount++;
}
num_wk[wkCount] = wk;
wkCount++;
}
if(op[numCount] == '=') break;
}
printf("--------------------------------\n");
// ここまでで、乗除は部分的に計算されて、wk_num, wk_op に確保されている
for(i = 0; i < wkCount; i++)
{
printf("%c %d\n", op_wk[i], num_wk[i]);
}
// 最終の計算
printf("--------------------------------\n");
result = 0;
for(i = 0; i < wkCount; i++)
{
result = calc(result, num_wk[i], op_wk[i]);
}
printf("Answer = %d", result);
return 0;
}
No.3
- 回答日時:
こまかく見てないけど
> if((op1=='+'|'-'|'*'|'/') && (op2=='+'|'-'|'*'|'/')){
PHPかなんかで正規表現の経験があるんですかね?
でも、C言語で、しかも、条件式として使うなら間違っています。
| 一つはビット毎のorを計算します。
'+'|'-'|'*'|'/' だと、
+を表わす文字コード or -を表わす文字コード or *を表わす文字コード or /を表わす文字コード
になります。
この書き方でするなら
((op1=='+') || (op1=='-' ) || (op1=='*' ) || (op1=='/' ))
とする必要があります。(わかりやすくするために括弧を付けました。)
他にもstrchrを使うとか方法はあります。
で、このifが成りたつときに、y○z を先に計算するようですけど
今までは条件が異常だったので、真になることが無く、全部x△yを先に計算していましたが、上の修正をすると、op1,op2の全ての組合せで真になるので、逆に、x△yを先に計算することがなくなります。
どちらを先に計算するのか、もう一度、条件をよく考えてみましょう
No.2
- 回答日時:
> 左辺に×、÷が来ても優先的に計算されません。
そんなコードは書かれていないので、当然です。
また、
> if((op1=='+'|'-'|'*'|'/') && (op2=='+'|'-'|'*'|'/')){
このコードは、あなたが意図してる動作とは違うと思います。
No.1
- 回答日時:
C言語はものすごく大昔にやったので文法的な間違いは指摘できません。
まず
if((op1=='+'|'-'|'*'|'/') && (op2=='+'|'-'|'*'|'/')){
の部分ですが、これですとop1,op2が+-*/のどの組み合わせでも
後ろのyとzの計算をしてしまうと思います。
条件的には[op1が+もしくは-]かつ[op2が*もしくは/]であれば
後ろのyとzの計算を優先する、としなければいけないと思います。
また、上の条件に当てはまらない場合のルートではxとyの計算のみを行って
zの計算が抜けているのでそれも追加する必要があると思います。
さらにanswerがint型であるため割り算のときに割り切れない数字の組み合わせですと
なにやら不都合が出ると思われます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- JavaScript jsで、switch文で書かれた分をif文にできませんか。 1 2022/07/28 15:10
- C言語・C++・C# C++のcase文の書き方 4 2023/02/24 20:50
- Excel(エクセル) 2つのVBAを一緒にしたら機能しなくなりました(エクセル) 7 2022/06/02 12:41
- JavaScript switch文のswitch(n)の部分を複数の値にするか、if文に変えてほしいです。 1 2022/07/27 17:18
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- JavaScript セレクトボックスを2つ設けて選択して初めてメッセを表示 1 2022/07/27 12:15
このQ&Aを見た人はこんなQ&Aも見ています
-
10代と話して驚いたこと
先日10代の知り合いと話した際、フロッピーディスクの実物を見たことがない、と言われて驚きました。今後もこういうことが増えてくるのかと思うと不思議な気持ちです。
-
秘密基地、どこに作った?
小さい頃、1度は誰もが作ったであろう秘密基地。 大人の今だからこそ言える、あなたの秘密基地の場所を教えてください!
-
「これはヤバかったな」という遅刻エピソード
寝坊だったり、不測の事態だったり、いずれにしても遅刻の思い出はいつ思い出しても冷や汗をかいてしまいますよね。
-
この人頭いいなと思ったエピソード
一緒にいたときに「この人頭いいな」と思ったエピソードを教えてください
-
14歳の自分に衝撃の事実を告げてください
タイムマシンで14歳の自分のところに現れた未来のあなた。 衝撃的な事実を告げて自分に驚かせるとしたら何を告げますか?
-
C言語で電卓を作成する。修正お願いします。
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
構文エラー";"が型の前にあり...
-
10進数からN進数に変換するプロ...
-
for文の中にswitch文はいれられ...
-
#if 1 #elseの意味について
-
C言語階乗の総和を求める
-
for文
-
配列を関数に渡す方法
-
配列を使って魔方陣
-
while文でπ/4の近似値を求める
-
C++での乱射ショットについて教...
-
raspberrypiでロータリエンコーダ
-
c言語です
-
getcの改行判定
-
C言語のプログラミング (基礎...
-
c言語プログラミングで1から100...
-
C言語です
-
while文について、c言語...
-
計算結果がlong型以上になる場...
-
while文を使った問題なのですが...
-
C言語 数字以外を入力させない...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
構文エラー";"が型の前にあり...
-
プログラム
-
#if 1 #elseの意味について
-
for文の中にswitch文はいれられ...
-
配列を使って魔方陣
-
getcの改行判定
-
配列を関数に渡す方法
-
プログラミングで二番目に大き...
-
C言語階乗の総和を求める
-
scanf関数を用いての加減乗除%...
-
C言語で電卓を作成する。
-
C言語 プログラム
-
C言語の二分法のプログラムにつ...
-
C言語のwhile文を使った素数判...
-
while文について、c言語...
-
10進数からN進数に変換するプロ...
-
C言語です
-
C言語でのトランプシャッフルに...
-
全角文字の判定
-
C言語のプログラミング (基礎...
おすすめ情報