表达式求值项目(多功能计算器)。该项目主要包含了10个模块,10项功能:
1:加法运算:主要进行两个数的加法运算,可进行计算整数和浮点数;
2:减法运算:主要进行两个数的减法运算,可进行计算整数和浮点数;
3:乘法运算:主要进行两个数的乘法运算,可进行计算整数和浮点数;
4:除法运算:主要进行两个数的除法运算,可进行计算整数和浮点数;增加了报错功能,由于除数不可以为0,当用户输入的除数为0的时候,该项目会出提示红色字体提示语句,提醒用户输入有误重新输入。
5:开平方根:主要进行某个数的开方,选择该功能时,计算器会提示输入需开方的数,然后打印出开方后的结果;
6:求某数的N次幂:选择该功能时,计算器会提示请输入需要计算的数x以及N的值,然后打印出N次幂后的结果;
7:进位制的转换:任意输入某个数字,可以将该数字分别转换为二进制,八进制,和十六进制。
8:表达式求值:
9:一元二次方程求解:
10:中缀表达式转换为后缀表达式:输入表达式后,计算器会对表达式进行判断。判断括号是否匹配,括号匹配完成后进行下一步表达式运算符匹配,匹配成功后输出其后缀表达式。如果匹配出现错误,出现红色字体警告,发出哔哔的声音,提示重新输入。
0:退出功能:选择退出时,出现一个退出界面。并退出程序。
小功能介绍:计算器包含了3个界面,开始界面,菜单界面,退出界面。采用多级变色提示音,红,绿,紫,黄。方便用户操作和查看。
#include<stdio.h> #include<windows.h> #include<stdlib.h> #include<math.h> #define MaxSize 10000 void print2(); void print1(); struct Stackop { char op[MaxSize]; int top; } stackop; struct StackNum { double num[MaxSize]; int top; } stacknum; int GetLevel(char op)//得到运算符的优先等级 { if(op=='+'||op=='-') return 1; if(op=='*'||op=='/') return 2; return 0; } double Add(double a,double b)//加法运算 { return a+b; } double Sub(double a,double b)//减法运算 { return a-b; } double Multi(double a,double b)//乘法运算 { return a*b; } double Div(double a,double b,double *result)//除法运算 { if(b==0) printf("除数不能为0\n"); return 0; *result=a/b; return 1; } int Calculate(double a,double b,char op,double *result) //用于对两个数进行运算 { switch(op) { case '+': *result=Add(a,b); return 1; case '-': *result=Sub(a,b); return 1; case '*': *result=Multi(a,b); return 1; case '/': return Div(a,b,result); default: return 0; } } void GetRpn(char *str,char *rpn) { int len=strlen(str),cnt=0,i; int isnum=0; stackop.top=-1; if(str[len-1]=='=') len--; if(str[0]=='-') { rpn[cnt++]='0'; rpn[cnt++]='#'; } for(i=0; i<len; i++) { if(str[i]>='0'&&str[i]<='9'||str[i]=='.') { rpn[cnt++]=str[i]; isnum=1; continue; } if(isnum) { rpn[cnt++]='#'; isnum=0; } if(str[i]=='('&&str[i+1]=='-') { rpn[cnt++]='0'; rpn[cnt++]='#'; } if(str[i]=='(') stackop.op[++stackop.top]=str[i]; else if(str[i]==')') { while(stackop.op[stackop.top]!='(') { rpn[cnt++]=stackop.op[stackop.top]; stackop.top--; } stackop.top--; } else if(stackop.top!=-1&&GetLevel(str[i])<= GetLevel(stackop.op[stackop.top])) { while(stackop.top!=-1&&GetLevel(str[i])<= GetLevel(stackop.op[stackop.top])) { rpn[cnt++]=stackop.op[stackop.top]; stackop.top--; } stackop.op[++stackop.top]=str[i]; } else { stackop.op[++stackop.top]=str[i]; } } if(isnum) rpn[cnt++]='#'; while(stackop.top!=-1) { rpn[cnt++]=stackop.op[stackop.top]; stackop.top--; } rpn[cnt]='\0'; } int GetAns(char *rpn,double *result) { int len=strlen(rpn),i; double fnum; int num,cnt; stacknum.top=-1; for(i=0; i<len; i++) { if(rpn[i]>='0'&&rpn[i]<='9') { num=cnt=0; fnum=0; while(rpn[i]!='#'&&rpn[i]!='.') { num=num*10+rpn[i]-'0'; i++; } if(rpn[i]=='.') { i++; while(rpn[i]!='#') { fnum=fnum+(rpn[i]-'0')*1.0/pow(10,++cnt); i++; } } fnum+=num; stacknum.num[++stacknum.top]=fnum; } else { double a,b,c; b=stacknum.num[stacknum.top]; stacknum.top--; a=stacknum.num[stacknum.top]; stacknum.top--; if(Calculate(a,b,rpn[i],&c)==0) { //计算失败 return 0; } else { stacknum.num[++stacknum.top]=c; } } } *result=stacknum.num[stacknum.top]; return 1; } int kuohao(char *str)//判断圆括号输入是否正确 { int i,len=strlen(str); int count=0; for(i=0;i<len;i++) { if(str[i]=='(') count++; if(str[i]==')') count--; } if(count!=0) { Beep(5000, 300); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED); printf("\n括号输入有错误\n"); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN); return 0; } else printf("\n括号匹配正确\n"); return 1; } int yunsunfu(char *str) { int i,len=strlen(str),k; printf("\n判断括号匹配输入是否正确:\n"); k=kuohao(str); if(k==0) return 0; printf("\n判断多项式运算符输入是否正确:\n"); for(i=0;i<len;i++) { if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/') { if(str[i+1]=='('||(str[i+1]>='0'&&str[i+1]<='9')) continue; else { Beep(5000, 300); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED); printf("\n多项式输入有错误\n"); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN); return 0; } } } printf("\n多项式输入正确\n"); return 1; } int main() { HANDLE hOut; // 获取输出流的句柄 hOut = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hOut, FOREGROUND_RED | // 前景色_红色 FOREGROUND_BLUE | // 前景色_蓝色 FOREGROUND_INTENSITY);// 加强 print1(); system("pause"); system("cls"); char str[MaxSize],rpn[MaxSize],ch; double bNumber, Number, Result,result; //给加减乘除定义的变量 double a, b, c,x, x1, x2, Rad; //一元二次方程定义变量 int Ary_10,n; //定义进制的变量 char string[32]; //二进制变量定义 while(1) { switch(menu()) { case 1: printf ("请输入被加数:"); scanf ("%lf",&bNumber); printf("请输入加数:"); scanf("%lf",&Number); Result = bNumber + Number; printf (" 结果是: %.2lf\n\n",Result); if(scanf("%c*%c",&ch)=='\0'); system("cls"); break; case 2: printf (" 请输入被减数:"); scanf ("%lf",&bNumber); printf (" 请输入减数:"); scanf ("%lf",&Number); Result = bNumber - Number; printf (" 结果是: %.2lf\n\n",Result); if(scanf("%c*%c",&ch)=='\0'); system("cls"); break; case 3: printf (" 请输入被乘数:"); scanf ("%lf",&bNumber); printf (" 请输入乘数:"); scanf ("%lf",&Number); Result = bNumber * Number; printf (" 结果是: %.2lf\n",Result); if(scanf("%c*%c",&ch)=='\0'); system("cls"); break; case 4: printf (" 请输入被除数:"); scanf ("%lf",&bNumber); printf (" 请输入除数:"); scanf ("%lf",&Number); if(Number==0) { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); // 获取控制台句柄 SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED); // 红色提示 printf("除数不可以为零\n"); if(scanf("%c*%c",&ch)=='\0'); system("cls"); break; } else { Result = bNumber / Number; printf (" 结果是: %.2lf\n\n",Result); if(scanf("%c*%c",&ch)=='\0'); system("cls"); break;} case 8: { int k; printf("输入所要经计算的表达式(如:a*b/(c-d))\n"); gets(str); if(gets(str)!=NULL) { k=yunsunfu(str); if(k!=0) { GetRpn(str,rpn); printf("其后缀表达式:%s\n",rpn); GetAns(rpn,&result); printf("表达式结果:%.2f\n",result); if(scanf("%c",&ch)=='\0'); system("cls"); break; } } } case 10: { int k; printf("请输入需要转换的表达式并以回车结束:\n"); gets(str); if(gets(str)!=NULL) { k=yunsunfu(str); if(k!=0) { GetRpn(str,rpn); printf("其后缀表达式:%s\n",rpn); if(scanf("%c",&ch)=='\0'); system("cls"); break; } else if(scanf("%c",&ch)=='\0'); system("cls"); break; } else printf("表达式为空,请核证后在输入.\n"); } case 9: { printf("请输入一元一次方程的a,b,c三个数:"); scanf("%lf%lf%lf",&a,&b,&c); getchar(); Rad = b*b - 4*a*c; if (Rad > 0) { x1 = -b + sqrt(Rad) / (2*a); x2 = -b - sqrt(Rad) / (2*a); printf("有两个解 x1 = %.2lf, x2 = %.2lf\n",x1,x2); } else if (Rad == 0) { x1 = -b / (2*a); printf("只有一个解 x1 = %.2lf\n",x1); } else { printf("无解\n"); } if(scanf("%c",&ch)=='\0'); system("cls"); break; } case 7: printf("请输入需要转换的十进制数:"); scanf("%d", &Ary_10); getchar(); itoa (Ary_10, string ,2); printf("二进制: %s\n",string); printf("八进制: %o\n",Ary_10); printf("十六进制: %x\n",Ary_10); if(scanf("%c",&ch)=='\0'); system("cls"); break; case 5: printf("请输入要开平方根的数X:\n"); scanf("%lf",&x); getchar(); result=sqrt(x); printf("%.2lf开根后的结果:%.2lf",x,result); if(scanf("%c",&ch)=='\0'); system("cls"); break; case 6: printf("请输入你要求幂的数X和指数n:"); scanf("%lf%d",&x,&n); getchar(); result=pow(x,n); printf("%.2lf的%d次幂为%.2lf",x,n,result); if(scanf("%c",&ch)=='\0'); system("cls"); break; case 0: print2(); return 0; } } return 0; } int menu() { int v; HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); // 获取控制台句柄 SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);// 设置为黄色 printf("\n"); printf ("┏ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┓\n"); printf ("┇请选择你要计算的方法: ┇\n"); printf ("┣ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┫\n"); printf ("┇ 加法请按_1 进制转换_7 ┇\n"); printf ("┇ 减法请按_2 表达式求值请按_8 ┇\n"); printf ("┇ 乘法请按_3 求一元二次方程_9 ┇\n"); printf ("┇ 除法请按_4 中缀表达式转化为后缀表达式_ 10┇\n"); printf ("┇ 求平方根_ 5 ┇\n"); printf ("┇ 求数的N次幂_6 退出_0 ┇\n"); printf ("┗ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┅ ┛\n"); printf ("Please write down the number:"); do { printf("请选择(0-10)\n"); scanf("%d",&v); } while(v<0||v>10); return v; } void print1() { printf("|_______________________________________ | \n"); printf("|| | | \n"); printf("|| 欢迎使用功能计算器 | | 本计算器能够进行 \n"); printf("||_____________________________________| | +,-,×,÷,\n"); printf("|| 图案仅供参考 | | ()等等 \n"); printf("||_____________________________________| | \n"); printf("| | \n"); printf("|___ ___ ___ ___ ___ ___ ___ ___ | \n"); printf("|________ ________ ________ ________ | \n"); printf("|| ⑨ | | ⑧ | | ⑦ | | × | | \n"); printf("||______| |______| |______| |______| | \n"); printf("|________ ________ ________ ________ | \n"); printf("|| ⑥ | | ⑤ | | ④ | | - | | \n"); printf("||______| |______| |______| |______| | \n"); printf("| _______ ________ ________ ________ | \n"); printf("|| ③ | | ② | | ① | | + | | \n"); printf("||______| |______| |______| |______| | \n"); printf("|________ ________ ________ ________ | \n"); printf("|| 〇 | | = | | AC | | ÷ | | \n"); printf("||______| |______| |______| |______| | \n"); printf("|| 版权所有,翻版必究 | \n"); } void print2() { system("cls"); HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); // 获取控制台句柄 SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_BLUE); // 设置为蓝色 printf("\n\n\n\n\n\n\n\n\t\t\t ##############################\n"); printf("\t\t\t # #\n"); printf("\t\t\t #----------谢谢使用----------#\n"); printf("\t\t\t # #\n"); printf("\t\t\t ##############################\n"); printf("\t\t\t --小李子制作\n "); }