C语言编写一个计算器(附全源代码)

2022-10-12 12:35:25

这个计算器其实是我老师布置的一个c语言大作业,捉摸着搞了那么久的东西不能浪费了吧,于是我分享下我的代码和大概思路
给个关注点个赞,后续我会分享更多我们学生党的作业问题

白嫖党们先看代码,我就先上上全代码,干!
前言:
为了达到目的,首先自学了栈:按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。其次查阅多方面资料结合所学知识进行编写而成。

(1)InitStack(S)初始化:初始化一个新的栈。

(2)Empty(S)栈的非空判断:若栈S不空,则返回TRUE;否则,返回 FALSE。

(3)Push(S,x)入栈:在栈S的顶部插入元素x,若栈满,则返回 FALSE;否则,返回TRUE。

(4)Pop(S)出栈:若栈S不空,则返回栈顶元素,并从栈顶中删除该元 素;否则,返回空元素NULL。

(5)GetTop(S)取栈顶元素:若栈S不空,则返回栈顶元素;否则返回 空元素NULL。

(6)SetEmpty(S)置栈空操作:置栈S为空栈。
(7) 常以top = -1表示空栈。

进栈(PUSH)算法
①若TOP≥n时,则给出溢出信息,作出错处理(进栈前首先检查栈是否已满,满则溢出;不满则作②);
②置TOP=TOP+1(栈指针加1,指向进栈地址);
③S(TOP)=X,结束(X为新进栈的元素)

退栈(POP)算法
①若TOP≤0,则给出下溢信息,作出错处理(退栈前先检查是否已为空栈,空则下溢;不空则作②);
②X=S(TOP),(退栈后的元素赋给X):
③TOP=TOP-1,结束(栈指针减1,指向栈顶)
(1)函数功能介绍及介绍:能够实现连续的运算,混合运算,基本上可以等同于手机上计算器。仅限于加减乘除的四则运算。(强调运算时的括号必须是英文版本的,否则运行会出错。写表达式也可以加上“=”和不加不影响运行结果,最终还是以回车进行结束得到结果)。如果能在visualc++运行,稍微调整一下,可以利用自带的功能设置一个界面,这样就可以完成跟手机自带那种计算器相同了。
加法运算:1+2回车可得3,连续运算1+2+3+4+5回车可得15
减法运算:1-2回车为-1,连续运算5-1-2回车得2
乘法:23回车6,连续运算23*4回车24

除法运算24/4回车6,24/2/2回车6、
混合运算:(5+2)*2回车14

(一)软件环境:Devc++

我用的这个软件哈,个人感觉这里功能简单,特别容易上手。看图说话,是不是很简单嘛,又不复杂。
在这里插入图片描述

(二)设计方案

根据自学所得栈进行数据和符号的存储再输出,先设立单独的数据栈符号栈,我们以top=-1为标准,判断其是否为空栈,当然也用到了学过的struct来构建栈,先把字符存进去再说,在里面我们要进行运算,然后再拿出来给我们看。于是我们就要四则运算,用switch四个case把加减乘除表达出来,这能进行简单的运算吧,那混合运算还带括号咋办,于是要用到判断优先级,加减,乘除分别同级,先左括号读到右括号我们要停止,这样就可以进行混合的运算了。后面我们经过调用前面设的函数想办法怎么把它输出来,我们就是要用到入栈顶什么的最后出栈,用个free(str)释放下内存打印出来得到结果。

(3)函数功能:

用到了第八章内容结构结合自学内容构造栈,switch表达式来判断优先级,主要用到的为自学的栈push进栈,pop出栈,top=-1划分是否为空字符,在前言写很清楚了。

(四)全代码:

#include<stdio.h>#include<stdlib.h>/*数据栈*/struct shuju//struct结构体构建栈{int data[100];int top;};/*符号栈*/struct fuhao{char symbol[100];int top;};voidInitOperateNum(struct shuju*StackNum)//数据栈非空{
    StackNum->top=-1;}voidInitOperateSymbol(struct fuhao*StackSymbol)//符号栈非空{  
    StackSymbol->top=-1;}/*存入数据栈*/voidInshuju(struct shuju*StackNum,int num){
	StackNum->top++;
	StackNum->data[StackNum->top]= num;}/*存入符号栈*/voidInfuhao(struct fuhao*StackSymbol,char ch){
	StackSymbol->top++;
	StackSymbol->symbol[StackSymbol->top]= ch;}/*读取数据栈*/intRandshuju(struct shuju*StackNum){return StackNum->data[StackNum->top];}/*读取符号栈*/charRandfuhao(struct fuhao*StackSymbol){return StackSymbol->symbol[StackSymbol->top];}/*从数据栈取出数据*/intPutshuju(struct shuju*StackNum){int x;
	x= StackNum->data[StackNum->top];
	StackNum->top--;return x;}/*从符号栈取出符号*/charPutfuhao(struct fuhao*StackSymbol){char c;
	c= StackSymbol->symbol[StackSymbol->top];
	StackSymbol->top--;return c;}/*符号优先级判断*/intjudge(char ch){if(ch=='('){return1;}if(ch=='+'|| ch=='-'){return2;}elseif(ch=='*'|| ch=='/'){return3;}elseif(ch==')'){return4;}}/*四则运算*/intMath(int v1,int v2,char c){int sum;switch(c){case'+':{
			sum= v1+ v2;break;}case'-':{
			sum= v1- v2;break;}case'*':{
			sum= v1* v2;break;}case'/':{
			sum= v1/ v2;break;}}return sum;}intmain(){struct shuju data;struct fuhao symbol;InitOperateNum(&data);//调用数据InitOperateSymbol(&symbol);//调用符号int i, t, sum, v1, v2;char c;
	i= t= sum=0;char v[100]={0};char*str=(char*)malloc(sizeof(char)*200);while((c=getchar())!='\n')//非空字符{
		str[i]= c;
		i++;}
	str[i]='\0';for(i=0; str[i]!='\0'; i++){if(i==0&& str[i]=='-'){
			v[t++]= str[i];}elseif(str[i]=='('&& str[i+1]=='-'){
			i++;
			v[t++]= str[i++];while(str[i]>='0'&& str[i]<='9'){
				v[t]= str[i];
				t++;
				i++;}Inshuju(&data,atoi(v));while(t>0){
				v[t]=0;
				t--;}if(str[i]!=')'){
				i--;Infuhao(&symbol,'(');}}elseif(str[i]>='0'&& str[i]<='9'){while(str[i]>='0'&& str[i]<='9'){
				v[t]= str[i];
				t++;
				i++;}Inshuju(&data,atoi(v));while(t>0){
				v[t]=0;
				t--;}
			i--;}else{if(symbol.top==-1){//如果符号栈没有元素,直接把符号放入符号栈Infuhao(&symbol, str[i]);}elseif(judge(str[i])==1){//如果此符号是'(',直接放入符号栈Infuhao(&symbol, str[i]);}elseif(judge(str[i])==2){//如果此符号是'+'或'-',判断与栈顶符号是优先级if(judge(Randfuhao(&symbol))==1){//如果栈顶符号是'(',放入符号栈Infuhao(&symbol, str[i]);}elseif(judge(Randfuhao(&symbol))==2){//如果栈顶符号是'+'或'-',则出栈运算while(symbol.top>=0&& data.top>=1){//循环出栈
						v2=Putshuju(&data);
						v1=Putshuju(&data);
						sum=Math(v1, v2,Putfuhao(&symbol));Inshuju(&data, sum);//将运算结果压入数据栈}Infuhao(&symbol, str[i]);//新符号进栈}elseif(judge(Randfuhao(&symbol))==3){//如果栈顶符号是'*'或'/',则进符号栈while(symbol.top>=0&& data.top>=1){//循环出栈
						v2=Putshuju(&data);
						v1=Putshuju(&data);
						sum=Math(v1, v2,Putfuhao(&symbol));Inshuju(&data, sum);//将运算结果压入数据栈}Infuhao(&symbol, str[i]);//新符号进栈}/*栈顶符号不可能是')',故不做判断*/}elseif(judge(str[i])==3){//如果此符号是'*'或'/',则判断与栈顶符号是优先级if(judge(Randfuhao(&symbol))==1){//如果栈顶符号是'(',放入符号栈Infuhao(&symbol, str[i]);}elseif(judge(Randfuhao(&symbol))==2){//如果栈顶符号是'+'或'-',则进符号栈Infuhao(&symbol, str[i]);//新符号进栈}elseif(judge(Randfuhao(&symbol))==3){//如果栈顶符号是'*'或'/',则出栈运算while(symbol.top>=0&& data.top>=1){//循环出栈
						v2=Putshuju(&data);
						v1=Putshuju(&data);
						sum=Math(v1, v2,Putfuhao(&symbol));Inshuju(&data, sum);//将运算结果压入数据栈}Infuhao(&symbol, str[i]);//新符号进栈}}elseif(judge(str[i])==4){// 如果此符号是')',则出栈运算直到遇到'('do{//循环出栈直到遇到'('
					v2=Putshuju(&data);
					v1=Putshuju(&data);
					sum=Math(v1, v2,Putfuhao(&symbol));Inshuju(&data, sum);//将运算结果压入数据栈}while(judge(Randfuhao(&symbol))!=1);Putfuhao(&symbol);//括号内运算结束后使'('出栈}}}free(str);//释放内存空间while(symbol.top!=-1){
		v2=Putshuju(&data);
		v1=Putshuju(&data);
		sum=Math(v1, v2,Putfuhao(&symbol));Inshuju(&data, sum);}printf("%d", data.data[0]);return0;}

我们来看看演示结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
好了,诸如类似不再演示了,代码讲解我觉得注释就够了,不关注点个赞吗?

(5)升级版代码

补充更新,看到很多人都觉得上面的代码太简单,为此再更新一个复杂的代码,可以执行科学计算,复杂四则运算:
在这里插入图片描述
在这里插入图片描述
完整代码:运行即可成功

#include"stdio.h"#include"stdlib.h"#include"string.h"#include"windows.h"#include"math.h"#include"conio.h"doublestringToDouble(char a[1000]){int i=0;char*p=(char*)malloc(1000*sizeof(char));int top=0;double sum=0;double mul=1;while(a[i]!='\0'&&a[i]!='.'){
		p[top]=a[i];
		top++;
		i++;}while(top!=0){
		top--;
		sum=sum+(p[top]-48)*mul;
		mul=mul*10;}if(a[i]=='.'){
		i++;
		mul=0.1;while(a[i]!='\0'){
			sum=sum+(a[i]-48)*mul;
			mul=mul/10;
			i++;}}return sum;}struct expre{double num;char sign;int ifNum;//标志位,1表示数字,0表示符号int end;//标志位,标志结构体数据末尾}*expre1,*expre2;struct numstack{double*base;}numstack1;//计算后缀表达式所需的数据栈struct signstack{char*base;}signstack1;//符号栈voidstructExpreRead(struct expre expre1[1000]){int i=0;while(expre1[i].end!=1){if(expre1[i].ifNum==1){printf("%f ",expre1[i].num);
			i++;}else{printf("%c ",expre1[i].sign);
			i++;}}}//四则运算doublecompute(double a,double b,char sign){if(sign=='+')return a+b;if(sign=='-')return b-a;if(sign=='*')return a*b;if(sign=='/')return b/a;}//符号优先级intsignnum(char x){if(x=='(')return1;if(x=='+'||x=='-')return2;if(x=='*'||x=='/')return3;}voidstringCopy(char*a,char*b,int start,int length){int i;int j=0;for(i=start;i<start+length;i++){
		a[
  • 作者:川川菜鸟
  • 原文链接:https://chuanchuan.blog.csdn.net/article/details/109726241
    更新时间:2022-10-12 12:35:25