わたしは、プログラムの初心者なのですが、力不足でプログラムが作れないのでご協力おねがいします。
データをすべて整数で演算子は、1個だけ用い、標準入力を受け取り、リターンキーが押されると、その解答を標準出力に表示するような、加減乗除の四則演算と整数剰余の演算を繰り返し行うことが可能な電卓プログラムを作りたいのですが、、、。

A 回答 (2件)

scanfで文字列データを受け取り、その文字列の先頭から順に 数字文字列 演算子文字 数字文字列 と解析し、変数に格納。

数字文字列を atoiなどで数値に変換し、演算子をキーに switch 文などで振り分け、演算。結果を printf。終わったらループで先頭の scanf。
で、どうでしょう?
    • good
    • 0

先ず、何処でつまずいてます?



つまずいてる所を教えて頂ければ、何かアドバイスが出来るかも知れません。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Q整数演算と実数演算の速度が違いのプログラム

こんにちは、C言語を独学しているものです。
すみませんがお助け頂けますでしょうか?

整数演算と実数演算の速度が違うという練習問題を
テキストから全く同じものを作り、コンパイラしたところです。

#include <stdio.h>
#include <time.h>
#define LOOP 200000L/*ループ回数*/

void main(void)
{
time_t i1,i2,r1,r2; /*Stored for time*/
long l; /*loop counter*/
int idata;
double ddata;

i1=time(NULL); /*Store the time of starting the integ culculation*/
for(l=0L;l < LOOP;l++)
{
idata += 10;
}
i2=time(NULL); /*store the time of ending the integ cal*/

r1=time(NULL); /*Store the time of starting the double cal.*/
for(l=0L;l < LOOP;l++)
{
ddata += 10.0;
}
r2=time(NULL); /*store the time of ending the double cal*/

/* display the stored the time in above by transferred to local time + how long it takes.*/

printf("integer start : %s",ctime(&i1));
printf("integer end: %s",ctime(&i2));
printf("interger process time total : %f(sec)\n",difftime(i2,i1));
printf("Real start : %s",ctime(&r1));
printf("Real end: %s",ctime(&r2));
printf("Real process time total : %f(sec)\n",difftime(r2,r1));
}



コンパイラ中に出たWarning

C:\Practice>bcc32 831.cpp
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
831.cpp:
Warning W8004 831.cpp 15: 'idata' is assigned a value that is never used in func
tion main()
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland



実行した結果
C:\Practice>831
integer start : Fri Aug 31 15:00:56 2012
integer end: Fri Aug 31 15:00:56 2012
interger process time total : 0.000000(sec)
Real start : Fri Aug 31 15:00:56 2012
Real end: Fri Aug 31 15:00:56 2012
Real process time total : 0.000000(sec)


両方ともStart timeの結果しかできていない、LOOPがうまく動いていないような気がします。
何度Programを見てもどこを直してよいのか分からないので どなたか教えて頂けないでしょうか?
(こんな簡単なこともわからずにお恥ずかしいです、、、。周りに教えてくれる先生がいないのでよろしくお願いします。)

こんにちは、C言語を独学しているものです。
すみませんがお助け頂けますでしょうか?

整数演算と実数演算の速度が違うという練習問題を
テキストから全く同じものを作り、コンパイラしたところです。

#include <stdio.h>
#include <time.h>
#define LOOP 200000L/*ループ回数*/

void main(void)
{
time_t i1,i2,r1,r2; /*Stored for time*/
long l; /*loop counter*/
int idata;
double ddata;

i1=time(NULL); /*Store the time of starting the integ culculation*/
for(l=0L;l < LOOP;l++)
{
idata += 10;...続きを読む

Aベストアンサー

startとendの差が0なのでそのように判断されたのでしょうか?

CPUが速いので200000回の計算はあっという間に終わってしまうのでしょう。
2000000000回にすれば差がでると思いますが…。

それでもだめなら二重ループにして回数を増やすとか…。

でもこの手のテストは最適化の問題だとか、コンパイラのデバグルーティンの挿入だとかの問題が隠されているように思いますから、最初のうちは簡単に確認したら次に進んだ方がいいかも。

Q四則演算のプログラム

自力で解きたかったのですが、二時間考えても、とけないので
投稿させていただきます。どこを直せばよいのでしょうか
実行するときは%プログラム名 + 5 12
と入力して実行したいです。加えて参照にしている部分の
%の扱いについても教えていただけると幸いです。
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char *argv[]){
char kigou;
double num1,num2;
kigou=atof(argv[1]);
num1=atof(argv[2]);
num2=atof(argv[3]);
if(kigou=='+'){
printf("%f+%f=%f\n",num1,num2,num1+num2);
}
else if(kigou=='-'){
printf("%f-%f=%f\n",num1,num2,num1-num2);
}
else if(kigou=='x'){
printf("%f*%f=%f\n",num1,num2,num1*num2);
}
else if(kigou=='/'){
printf("%f/%f=%f\n",num1,num2,num1/num2);
}
/* else if(kigou=='%'){
printf("%f%%f=%f\n",num1,num2,num1%num2);
}*/
else{
printf("Please input +,-,x,%%.\n");}


}

自力で解きたかったのですが、二時間考えても、とけないので
投稿させていただきます。どこを直せばよいのでしょうか
実行するときは%プログラム名 + 5 12
と入力して実行したいです。加えて参照にしている部分の
%の扱いについても教えていただけると幸いです。
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char *argv[]){
char kigou;
double num1,num2;
kigou=atof(argv[1]);
num1=atof(argv[2]);
num2=atof(argv[3]);
if(kigou=='+'){
printf("%f+%f=%f\n",num1,num2,...続きを読む

Aベストアンサー

★まず引数 argv、argc とは?
・『argv』はコマンドラインの引数を、空白文字で区切ってその文字列をポインタへの配列に
 セットします。『char *argv[]』とはその定義です。
・『argc』はコマンドラインの引数を、空白文字で区切った文字列の個数です。
・よって『sample.exe abc def 123 /s /o』というコマンドラインならば、
 argc=6
 argv[0]="sample.exe" ←プログラム名など(処理系によっては空文字列かも)
 argv[1]="abc"
 argv[2]="def"
 argv[3]="123"
 argv[4]="/s"
 argv[5]="/o"
 argv[6]=NULL ←NULLポインタがセット
・となります。

●本題
・第一引数の記号は『atof』を使わずに『kigou=argv[1][0];』とすれば良い。
・argv[1]="abc"のとき、
 argv[1][0]='a'
 argv[1][1]='b'
 argv[1][2]='c'
 argv[1][3]='\0'
・として取り出せます。

●サンプル
int main( int argc, char *argv[] )
{
 char kigou = argv[1][0]; ←ここがポイント
 double num1 = atof(argv[2]);
 double num2 = atof(argv[3]);
 
 switch ( kigou ){ ←switch 文のほうが分かりやすいよ
  case '+': printf( "%f+%f=%f\n", num1, num2, (num1 + num2) ); break;
  case '-': printf( "%f-%f=%f\n", num1, num2, (num1 - num2) ); break;
  case 'x': printf( "%f*%f=%f\n", num1, num2, (num1 * num2) ); break;
  case '/': printf( "%f/%f=%f\n", num1, num2, (num1 / num2) ); break;
  case '%': printf( "%f%%%f=%f\n", num1, num2, fmod(num1,num2) ); break; ←ここも重要
  default: printf( "Please input +,-,x,/,%%.\n" ); ←『/』を追加
 }
 return( 0 );
}

最後に:
・浮動小数点の『%』は関数『fmod』を使います。→直接『%』演算子を使えません。
・整数値の『char』、『short』、『int』、『long』型などは直接『%』演算子で剰余を
 計算できますが、浮動小数点の『float』、『double』型では関数の『fmodf』、『fmod』
 の関数を使います。→テキスト(教科書)などの算術演算を参照して下さい。
・注意。割り算と剰余の場合に『num2』が『0』だと『ゼロ除算エラー』が発生します。
・『num2』が『0』のときは計算不能というエラーを表示した方が良いです。
・以上。おわり。

参考URL:http://www.bohyoh.com/CandCPP/C/Library/fmod.html

★まず引数 argv、argc とは?
・『argv』はコマンドラインの引数を、空白文字で区切ってその文字列をポインタへの配列に
 セットします。『char *argv[]』とはその定義です。
・『argc』はコマンドラインの引数を、空白文字で区切った文字列の個数です。
・よって『sample.exe abc def 123 /s /o』というコマンドラインならば、
 argc=6
 argv[0]="sample.exe" ←プログラム名など(処理系によっては空文字列かも)
 argv[1]="abc"
 argv[2]="def"
 argv[3]="123"
 argv[4]="/s"
 argv[5]="/o"
...続きを読む

Q四則演算プログラム(入力式の表示版)

プログラミング初心者の大学生です。よろしくお願いいたします。

 計算式入力し、計算結果を表示するプログラムの作成方法がわかりません。
条件としては、数値は実数の入力を可能とし、括弧の利用は考えないとのことです。
 
 【実行例】

 ・計算式="5.2+20*2-3"
 ・結果=42.2

 いきなり難易度が上がっため、自分の手には負えませんでした…。
どなたか、良いお答えをよろしくお願いいたします。

Aベストアンサー

今頃このような問題をしているという事は大学1年生位でしょうかね?
確かにこの前始めた人にこの問題は結構辛いですね。

回答例・・というか99%答えなんですけど^^;
サンプルプログラムを書きましたんで、見てください。

入門者さんみたいなのでなるべく簡単な関数や書き方で書きました。

#include<stdio.h>
#include<string.h>
int num[20],atainokosu;
char input_str[100],enzanshi[10],str[10][20];

int a2i(char*str){
int cnt;
int num=0;

for (cnt = 0; (str[cnt] >= '0') && (str[cnt] <= '9') ; cnt++) {
num = 10 * num + (str[cnt]-'0');
}
return num;
}

int getch(){
int i=0;

while( ( input_str[i] = getchar() ) != EOF)
i++;
input_str[i-1]='\0';
return 0;
}

int divch(){

int i=0,j=0,s=0;

while(input_str[i]!='\0'){
if(input_str[i] == '+' || input_str[i]=='-' || input_str[i]=='*' || input_str[i] =='/'){
enzanshi[j]=input_str[i];
j++;
s=0;
}
else{
str[j][s]=input_str[i];
s++;
}
i++;
}
atainokosu=j;
for(i=0;i<=j;i++)
num[i]=a2i(str[i]);

return 0;
}

int calc(){
int i=0,j;
while(i<=atainokosu){
if(enzanshi[i]=='*'){
num[i]=num[i]*num[i+1];
j=i;
while(j<=atainokosu){
num[j+1]=num[j+2];
enzanshi[j]=enzanshi[j+1];
j++;
}
atainokosu--;
}
else if(enzanshi[i]=='/'){
num[i]=num[i]/num[i+1];
j=i;
while(j<=atainokosu){
num[j+1]=num[j+2];
enzanshi[j]=enzanshi[j+1];
j++;
}
atainokosu--;
}
else
i++;
}
i=0;
while(0<atainokosu){
if(enzanshi[i]=='+'){
num[i]=num[i]+num[i+1];
j=i;
while(j<=atainokosu){
num[j+1]=num[j+2];
enzanshi[j]=enzanshi[j+1];
j++;
}
atainokosu--;
}
else if(enzanshi[i]=='-'){
num[i]=num[i]-num[i+1];
j=i;
while(j<=atainokosu){
num[j+1]=num[j+2];
enzanshi[j]=enzanshi[j+1];
j++;
}
atainokosu--;
}
else
i++;
}
return 0;
}
int main(){
int i;
getch();
divch();
calc();
printf("計算式=\"%s\"\n結果=%d\n",input_str,num[0]);

return 0;
}

これは整数の四則演算ができるプログラムです。
浮動小数点には対応していません。
例:
「10/5+2*5」と入力し、エンターを押す。その後Ctrl + Zを押してエンターを押す。すると計算結果が表示される。

100%答えを書いてしまってはよくないので(といっても99%答えですけど)
ココまでプログラム書いたんで、今度は小数点も計算できるように改良してください。
ヒントは#2さんが既におっしゃっています。
4.strtod して値を返す
この辺をヒントに頑張ってください。
わかれば1分で完成すると思います。

プログラムの中身は次に説明します。

頑張ってください。

今頃このような問題をしているという事は大学1年生位でしょうかね?
確かにこの前始めた人にこの問題は結構辛いですね。

回答例・・というか99%答えなんですけど^^;
サンプルプログラムを書きましたんで、見てください。

入門者さんみたいなのでなるべく簡単な関数や書き方で書きました。

#include<stdio.h>
#include<string.h>
int num[20],atainokosu;
char input_str[100],enzanshi[10],str[10][20];

int a2i(char*str){
int cnt;
int num=0;

for (cnt = 0; (str[cnt] >= '0') && (...続きを読む

Q2つ分数の四則演算を行うプログラム

<要求事項>
分数は、 例)1|3 のように表す。
1.分母がゼロの時はエラーとする。
2.除算において、除数がゼロの入力エラーに対しては、再入力するように促す。
3.以下範囲の整数(分子、分母にかかわらず)に対して、正しく計算できるようにする。
  -2147483648 ~ 2147483647

4.計算結果については,分母が1の時には分子のみ表示。分数がの時には0のみを表示。最終計算結果は既約分数にする。分数が負数の場合、-を分数の前に表示。

#include <stdio.h>
#include <math.h>

int main(void)
{
int b,d; /* 分母*/
int a,c; /* 分子*/
int sign,sign2,sign3,sign4;
int yakusu,yakusu2,yakusu3,yakusu4; /* 最大公約数*/

printf("分母= ");
scanf("%d",&b);

printf("分子= ");
scanf("%d",&a);

if(b==0){
printf("分母が0です。入力が誤っています。\n"); /*分母が0ならエラーとする*/
return 0;
}
if (a==0){
printf("分数1= 0\n"); /*分子が0のとき*/
}
else{
printf("分数1=%d|%d\n",a,b); /*一つ目の分数*/
}
printf("\n");

printf("分母= ");
scanf("%d",&d);

printf("分子= ");
scanf("%d",&c);

if(d==0){
printf("分母が0です。入力が誤っています。\n"); /*分母が0ならエラーとする*/
return 0;
}
if (c==0){
printf("分数2= 0\n"); /*分子が0のとき*/
}
else{
printf("分数2=%d|%d\n",c,d); /*二つ目の分数*/
}
printf("\n");

/* 足し算:a|b + c|d = (a*d + b*c) | (b*d) */
printf("足し算:%d|%d + %d|%d\n",a,b,c,d);

yakusu = gcd(abs(a*d + b*c),abs(b*d)); /*最大公約数を求める*/
sign = (a*d + b*c)/abs(a*d + b*c) * (b*d/abs(b*d));

if(sign * abs(a*d + b*c)/yakusu == 0){ /*分子が0となる時*/
printf("0\n");
}
if (abs(b*d)/ yakusu!= 1){
printf("既約分数は %d|%d\n" ,sign * abs(a*d + b*c)/yakusu , abs(b*d)/yakusu );
}
else{
printf("既約分数は %d\n" ,sign * abs(a*d + b*c)/yakusu ); /*分母が1の場合*/
}

printf("\n");

/* 引き算:a|b - c|d = (a*d - b*c) | (b*d) */
printf("引き算:%d|%d - %d|%d\n",a,b,c,d);

yakusu2 = gcd(abs(a*d - b*c),abs(b*d)); /*最大公約数を求める*/
sign2 = (a*d - b*c)/abs(a*d - b*c) * (b*d/abs(b*d));

if(sign2 * abs(a*d - b*c)/yakusu2 == 0){ /*分子が0となる時*/
printf("0\n");
}
if (abs(b*d)/ yakusu2!= 1){
printf("既約分数は %d|%d\n" ,sign2 * abs(a*d - b*c)/yakusu2 , abs(b*d)/yakusu2 );
}
else{
printf("既約分数は %d\n" ,sign2 * abs(a*d - b*c)/yakusu2 );
}

printf("\n");

/* 掛け算:a|b * c|d = (a*c) | (b*d) */
printf("掛け算:%d|%d * %d|%d\n",a,b,c,d);

yakusu3 = gcd(abs(a*c),abs(b*d)); /*最大公約数を求める*/
sign3 = (a*c)/abs(a*c) * (b*d/abs(b*d));

if(sign3 * abs(a*c)/yakusu3 == 0){ /*分子が0となる時*/
printf("0\n");
}
if (abs(b*d)/ yakusu3!= 1){
printf("既約分数は %d|%d\n" ,sign3 * abs(a*c)/yakusu3 , abs(b*d)/yakusu3 );
}
else{
printf("既約分数は %d\n" ,sign3 * abs(a*c)/yakusu3 ); /*分母が1の場合*/
}

printf("\n");

/* 割り算:a|b / c|d = (a*d) | (b*c) */
printf("割り算:%d|%d / %d|%d\n",a,b,c,d);

yakusu4 = gcd(abs(a*d),abs(b*c)); /*最大公約数を求める*/
sign4 = (a*d)/abs(a*d) * (b*c/abs(b*c));

if(sign4 * abs(a*d)/yakusu4 == 0){ /*分子が0となる時*/
printf("0\n");
}
if (abs(b*c)/ yakusu4!= 1){
printf("既約分数は %d|%d\n" ,sign4 * abs(a*d)/yakusu4 , abs(b*c)/yakusu4 );
}
else{
printf("既約分数は %d\n" ,sign4 * abs(a*d)/yakusu4 );/*分母が1の場合*/
}
return 0;
}
int gcd(int x,int y){
/* ユークリッド互除法*/
int z;
if( (x <= 0) || (y <= 0) ){
return -1;
}
z = x % y;
while (z != 0){
x = y;
y = z;
z = x % y;
}
return y;
}

>>大学の課題です。現在の状態は上記の通りです。このプログラムだと、答えの既約分数が0になると表示できなかったり、桁が大きい数で計算しようとすると値がおかしくなってしまいます。
どなたかプログラム改良にご助力願えないでしょうか?

<要求事項>
分数は、 例)1|3 のように表す。
1.分母がゼロの時はエラーとする。
2.除算において、除数がゼロの入力エラーに対しては、再入力するように促す。
3.以下範囲の整数(分子、分母にかかわらず)に対して、正しく計算できるようにする。
  -2147483648 ~ 2147483647

4.計算結果については,分母が1の時には分子のみ表示。分数がの時には0のみを表示。最終計算結果は既約分数にする。分数が負数の場合、-を分数の前に表示。

#include <stdio.h>
#include <math.h>

int ma...続きを読む

Aベストアンサー

No.2です
>オーバーフローというものは良く分からないのですが、アドバイスを踏まえて色々やってみます。

オーバーフローの概念だけ簡単に。
例えば、0~99までが入る変数型「sample」があったとします(ここでわかりやすく10進数でいきます)

sample a, b, c;
a = 99;
b = 99;
c = 0;
c = a * b;

という計算を行った場合、cの値はいくつになるでしょうか?
単純に「a * b」を計算すると「99 * 99 = 9801」となります。
しかし、sample型で扱うるの「0~99」です。
そのため100以上の値は「c」に格納することができず桁あふれ(オーバーフロー)が発生してしまいます。
このため、桁あふれ分はcに格納することができず「c = a * b」の結果「c」には桁あふれで残った(sample型に格納できる)分「1」が入ることになります。

注:あくまで概念の説明です。

Q四則演算プログラム

2つの数字を四則演算するプログラムを作ろうと
思っているんですが、

(1)関数atoiを使う、
(2)int main(int argc, char +argv[])と
 宣言する、
(3)足し算の場合のみ、2つ以上の数字を計算できる

ということが条件なんですけど、どなたか
プログラムがどのようなものか教えていただけ
ませんか??

Aベストアンサー

> ということが条件なんですけど、どなたか
> プログラムがどのようなものか教えていただけ
> ませんか??

提示されている条件をすべて満たすことは不可能です。特に(2)


人気Q&Aランキング

おすすめ情報