C语言实现简单计算器

2022-10-20 13:25:32

一、背景

自己希望通过这个处女帖,来互相学习、经验积累,故将本次课设的代码发到CSDN,希望可以得到网友们的指点。我用的是DEVC++,作出来后,能实现简单的整数加减乘除。

二、代码

1、数据结构

下面展示全部的头文件。

//简单的计算器
#include<iostream>
#include<cstring>
#include<math.h>
#include<windows.h>
#defineE10000000//定义一个极大值,读取到加减乘除时将加减乘除+E,//压入int类型栈里,表示加减乘除
#defineMAXSIZE100//栈容量

using namespace std;
typedef char ElemType;

typedef struct{//定义char栈
	ElemType*base;//栈底指针
	ElemType*top;//栈顶指针
	int stacksize;//栈的容量}SqStack;
typedef struct{//定义int栈
	int*base;
	int*top;
	int stacksize;}SqStack_int;//分别初始化char、int类型栈
intInitStack(SqStack&S);//S为要初始化的栈
intInitStack_int(SqStack_int&S);//S为要初始化的栈//分别做char、int类型栈的入栈出栈
intPush_char(SqStack&S,ElemType e);//S为要初始化的栈 ,e为要入栈元素
intPush_int(SqStack_int&S,int e);//S为要初始化的栈 ,e为要入栈元素
charPop_char(SqStack&S,ElemType&e);//S为要初始化的栈 ,e为要出栈元素
charPop_int(SqStack_int&S,int&e);//S为要初始化的栈 ,e为要出栈元素
ElemTypeGetTop(SqStackS);//返回ElemType类型S栈顶元素
intEmpty(SqStackS);//S栈判空
intLength(SqStack_intS);//返回int类型S栈元素个数
intreplace(char a);//给运算符a赋值
intcompare(char a,char b);//a为栈顶运算符,b为扫描到的运算符,返回他们优先级对比的结果voidcount(int a[],int m);//计算 后缀表达式a的值并输出 ,m表示表达式位数
intjisuan();//中缀转后缀,并且划分各个整数 ,返回运算状态,s值控制是否进行该操作voidxunhuan(int x);//循环函数,让用户循环多次使用 ,x值控制是否循环和判断用户输入正确与否voidrel(SqStack_int&S,SqStack&S_num,SqStack&S_fuhao,char x);//判断优先级并且入栈出栈

2、弟弟行为的编程

intmain(){//主函数system("mode con cols=38 lines=25");//窗口宽度高度
	char s;//char类型的s做判断用户是否进入计算器的控制元素printf("欢迎使用简单计算器!\n该计算器可以运算多位的正负整数\n");//使用指导system("title 简单计算器");//设置cmd窗口标题system("color 0c");// 设置窗口颜色printf("是否使用计算器(Y/N):");//用户输入Y/N进行选择是否进入计算器
	cin>>s;//用户输入if(s=='N')printf("已退出计算器!");//N表示退出,执行退出while(s!='N'){//如果不是N,有两种情况进行判断和循环if(s=='Y'){//第一种情况:Y则进入计算器xunhuan(jisuan());//运用循环函数,进行递归循环,实现循环计算break;//当上个循环只有用户选择退出时才会结束循环,之后直接break,结束程序}elseprintf("输入错误,请重新输入,是否使用计算器(Y/N):");//第二种情况 :输入错误(不是Y也不是N),继续让用户选择
			cin>>s;//输入s进行循环}return0;//程序正常结束}




intInitStack(SqStack&S)//SqStack类型S栈初始化{S.base=newElemType[MAXSIZE];//分配空间if(!S.base)return-1;//如果分配失败返回-1S.top=S.base;//初始化为空栈S.stacksize=MAXSIZE;//S的容量设为MAXSIZEreturn1;}//同上个S栈的初始化 ,只不过这里是SqStack_int 类型的S栈
 intInitStack_int(SqStack_int&S){S.base=newint[MAXSIZE];if(!S.base)return-1;S.top=S.base;S.stacksize=MAXSIZE;return1;} 
 
 
 
intPush_char(SqStack&S,ElemType e)//将元素e入SqStack类型的S栈{if(S.top-S.base==S.stacksize)return-1;//如果栈满则无法入栈*S.top++=e;//将e赋值给top指针所指位置,栈顶指针top加一return1;}//同上面入栈操作,只是入栈元素类型 和栈类型不同
intPush_int(SqStack_int&S,int e){if(S.top-S.base==S.stacksize)return-1;*S.top++=e;return1;}



charPop_char(SqStack&S,ElemType&e)//S栈栈顶元素出栈{if(S.top==S.base)returnprintf("错误");//如果栈空,返回错误
	e=*--S.top;//栈顶指针减一,之后栈顶元素值赋值给 ereturn e;//返回e值}//同上面操作,只是类型不同
charPop_int(SqStack_int&S,int&e){if(S.top==S.base)returnprintf("错误");
	e=*--S.top;return e;}



ElemTypeGetTop(SqStackS)//取S栈栈顶元素{if(S.top!=S.base)//如果S栈非空返回 栈顶元素值return*(S.top-1);elsereturn'#';//否则返回"#"}

intEmpty(SqStackS){//判断S栈是否为空if(S.top-S.base==0)//栈空返回1,否则返回0return1;return0;}

intLength(SqStack_intS)//求S栈的元素个数{return(S.top-S.base);}


intreplace(char a)//判断a符号优先级{switch(a)//考虑运算符a的类型,并且对相应的类型赋值{case'+':return1;case'-':return1;case'*':return2;case'/':return2;case'(':return0;case'#':return0;}}
intcompare(char a,char b)//对比a和b符号的优先级{return(replace(a)<replace(b))?1:0;//如果b优先级大于a则返回0,否则返回1}voidcount(int a[],int m)//计算元素个数m的表达式a{
	SqStack_int Sw;//定义一个SqStack_int类型的栈SwInitStack_int(Sw);//Sw栈初始化for(int h=0;h<m;h++){//循环遍历表达式,判断其中数字是代表运算符还是数字//10000045、10000042、10000047、10000043分别对应4个运算符if(a[h]!=10000045&&a[h]!=10000042&&a[h]!=10000047&&a[h]!=10000043){Push_int(Sw,a[h]);//数字入栈}else{//如果出现上述4个数字,表示是运算符
			int c,d,sum;//分类讨论+—*/四种情况,并且求值,最后入栈if(a[h]==10000045){Pop_int(Sw,c);Pop_int(Sw,d);
					sum=d-c;Push_int(Sw,sum);}if(a[h]==10000043){Pop_int(Sw,c);Pop_int(Sw,d);
					sum=c+d;Push_int(Sw,sum);}if(a[h]==10000042){Pop_int(Sw,c);Pop_int(Sw,d);
					sum=c*d;Push_int(Sw,sum);}if(a[h]==10000047){Pop_int(Sw,c);Pop_int(Sw,d);
					sum=d/c;Push_int(Sw,sum);}}}
	int x;Pop_int(Sw,x);//将最后的栈内计算出的最后结果出栈,赋值给xprintf("%d\n",x);//输出最后结果x}

intjisuan()//进行中缀转后缀{printf("请输入您想计算的表达式(输入#退出):\n");//定义SqStack_int类型的栈S,用于存储int类型的最终表达式
	SqStack_intS;//定义SqStack类型的S_num、S_fuhao,用于中缀转后缀用
	SqStack S_num,S_fuhao;InitStack_int(S);InitStack(S_num);InitStack(S_fuhao);
	int tag=0;//tag的值表示输入的数字以后应该转化为几位数
	char e;//e用来存储后面的出栈元素
	char ex[100];//定义一个容量为100的字符串,供用户输入表达式
	cin>>ex;//输入if(ex[0]=='#')return1;//如果输入#号表示用户不想继续使用计算器了,则返回1for(int x=0;ex[x]!='\0';x++){//判断输入的内容合不合规if(ex[x]!='+'&&ex[x]!='-'&&ex[x]!='*'&&ex[x]!='/'&&ex[x]!='('&&ex[x]!=')'&&
	ex[x]!='1'&&ex[x]!='2'&&ex[x]!='3'&&ex[x]!='4'&&ex[x]!='5'&&ex[x]!='6'&&ex[x]!='7'&&ex[x]!='8'&&
	ex[x]!='9'&&ex[x]!='0'){printf("错误");return-1;//如果输入的不合规返回-1}}for(int i=0;ex[i]!='\0';i++){//开始遍历字符串if(ex[i]!='+'&&ex[i]!='-'&&ex[i]!='*'&&ex[i]!='/'&&ex[i]!='('&&ex[i]!=')'){//遍历到元素是数字if(i==0&&ex[i]=='0'){//考虑第一个数字是 0的情况
				int a=ex[i]-48;//将字符类型的0转化成int类型的0Push_int(S,a);//入S栈continue;//跳过该i值 ,进行下个i值循环}
			tag++;//tag记录数字个数,后面Pop划成一个整数用Push_char(S_num,ex[i]);//将ex[i] 的值入S_num栈}else{//遍历到运算符if(i==0&&ex[i]=='-'){//讨论如果第一个数是负数情况
				int cn=0,mk=0;for(int j=1;ex[i+j]!='+'&&ex[i+j]!='-'&&ex[i+j]!='*'&&ex[i+j]!='/';j++){//第一个负数格式为 -xx 是一个整数
					cn++;//判断第一个元素是负数,除第一个负号外,数字所占的位数}for(int k=0;k<cn;k++){// 把入的数字元素划成整数
					mk+=(ex[k+1]-48)*pow(10,cn-k-1);//每位累加,最后 mk为最终整数值}Push_int(S,0-mk);//压入int栈一个负数,0-mk//跳过这个负数继续向后遍历
				i+=cn;continue;}if(ex[i]=='('&&ex[i+1]=='-'){//讨论如果是括号内负数情况
				int cn=0,mk=0;Push_char(S_fuhao,ex[i]);for(int j=2;ex[i+j]!=')'&&ex[i+j]!='+'&&ex[i+j]!='-'&&ex[i+j]!='*'&&ex[i+j]!='/';j++){//负数格式必须为(-xx) xx是一个整数
					cn++;}for(int k=0;k<cn;k++){// 把入的数字元素划成整数
					mk+=(ex[i+cn+1-k]-48)*pow(10,k);}Push_int(S,0-mk);//压入int栈一个负数,0-mk
				i+=cn+1;//跳过这个负数继续向后遍历continue;//进行下一个i值循环}if(tag==0){//如果扫描到符号前,tag==0,表示之前没有数字字符if(Empty(S_fuhao)||ex[i]=='(')//如果是空栈或者左括号{Push_char(S_fuhao,ex[i]);//直接入S_fuhao栈continue;//进行下一个i值循环}rel(S,S_num,S_fuhao,ex[i]);}//如果扫描到运算符之前tag!=0,则需先Pop出数字字符,进行整合成一个整数else{
				int a=0;//a是最后的数字元素整合结果for(int lk=0;lk<tag;lk++){
					char ad;Pop_char(S_num,ad);
					int ax=ad;
					a+=(ax-48)*pow(10,lk);}Push_int(S,a);//将a入S栈
				tag=0;//最后将计数器tag置零rel(S,S_num,S_fuhao,ex[i]);}}}if(tag!=0){//处理字符串最后的数字,进行出栈求值再入栈
		int a=0;for(int lk=0;lk<tag;lk++){
				char ad;Pop_char(S_num,ad);
				int ax=ad;
				a+=(ax-48)*pow(10,lk);}Push_int(S,a);
			tag=0;}while(!
  • 作者:一方通行ACC
  • 原文链接:https://blog.csdn.net/weixin_53070760/article/details/118636501
    更新时间:2022-10-20 13:25:32