#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <stdbool.h>
#include <malloc.h> #define STACK_SIZE 100
#define APPEND_SIZE 10 struct SNode
{
double data; //存放操作数或者计算结果
char ch; //存放运算符
};
struct Stack //顺序栈,用于计算表达式
{
struct SNode *top;
struct SNode *base;
int size;
}; int InitStack(struct Stack *S); //初始化栈
int DestroyStack(struct Stack *S); //销毁栈
int ClearStack(struct Stack *S); //清空栈
int GetTop(struct Stack S, struct SNode *Elem); //取出栈顶结点并返回节点值
int Push(struct Stack *S, struct SNode Elem); //入栈
int Pop(struct Stack *S, struct SNode *Elem); //出栈 void OutPut(char *pFormula, double CurrentNum, int Mflg);//主循环格式输出
int RtOpe(char **pKey, char *pIn); //判断操作符以及计算器功能
double Cal(char *pFormula); //计算表达式
int Check(char *pFormula); //检查表达式 char Judge(struct SNode Popc, struct SNode Cr);//比较运算符优先级
double Operate(double Numa, char Opr, double Numb);//计算a,b经过opr运算后的结果
char *killzero(char *Str, double Result);//消除末尾的0 int main(void)
{
char Formula[]={'\0'};
char *pFormula=Formula;
char In[]; int M=,Mflg=;
char *Key[]={"+","-","*","/","=","MC","MR","MS","M+","M-","CE","C","~","sqr","rec","(",")"};
char **pKey=Key;
double CurrentNum =;
bool fg=false; OutPut(pFormula , CurrentNum, Mflg);
while ()
{
scanf("%s", In);
if(isdigit(In[]) != )//当前输入的是数字
{
CurrentNum=atof(In);
if(false == fg)
{
strcat(pFormula, In);
}
fg=false;
}
else //当前输入的是操作符
{
switch(RtOpe(pKey, In))//判断是什么操作符
{
case ://"+" 写入算式
{
strcat(pFormula, In);
fg=false;
break;
}
case ://"-" 写入算式
{
strcat(pFormula, In);
fg=false;
break;
}
case ://"*" 写入算式
{
strcat(pFormula, In);
fg=false;
break;
}
case ://"/" 写入算式
{
strcat(pFormula, In);
fg=false;
break;
}
case ://"=" 计算算式的值
{
CurrentNum=Cal(pFormula);
fg=false;
break;
}
case ://"MC" 清除存储器中的值
{
M=;
Mflg=;
fg=false;
break;
}
case ://"MR" 显示存储器中的值
{
CurrentNum=M;
fg=false;
break;
}
case ://"MS" 将当前的值存放到存储器中
{
M=CurrentNum;
Mflg=;
fg=true;
break;
}
case ://"M+" 将当前值和存储器中的值相加并存储
{
M+=CurrentNum;
fg=false;
break;
}
case ://"M-" 将存储器中的值减去当前值并存储
{
M-=CurrentNum;
fg=false;
break;
}
case ://"CE" 清除显示的数字
{
CurrentNum=;
fg=false;
break;
}
case ://"C" 归零,清除当前的计算
{
CurrentNum=;
Formula[]='\0';
fg=false;
break;
}
case ://"~"改变当前值的正负
{
CurrentNum=-CurrentNum;
fg=false;
break;
}
case ://"sqr"求当前值的平方根
{
if(CurrentNum >= )
{
CurrentNum=sqrt(CurrentNum);
}
else
{
printf("\nError Calculate !\n");
}
fg=false;
break;
}
case ://"rec"求显示数字的1/x的值
{
if(CurrentNum != )
{
CurrentNum=/CurrentNum;
}
else
{
printf("\nError Calculate !\n");
}
fg=false;
break;
}
case ://"(" 写入算式
{
strcat(pFormula, In);
fg=false;
break;
}
case ://")" 写入算式
{
strcat(pFormula, In);
fg=false;
break;
}
default:printf("\nError input !\n");
fg=false;
break;
}
}
OutPut(pFormula, CurrentNum, Mflg);
}
return ;
} void OutPut(char *pFormula, double CurrentNum, int Mflg)//主循环格式输出
{
system("cls");
int i=;
char Str[];
char *pStr=Str;
double num=CurrentNum;
if(num >= )
{
num=;
}
printf("\n"); while (*(pFormula+i) != '\0')
{
printf("%c", *(pFormula+i));
i++;
}
printf("\n");
if(Mflg == )
{
printf("M");
}
printf("\t%s\n", killzero(pStr, num));
printf("\nMC\tMR\tMS\tM+\tM-\tCE\tC\t~\tsqr\trec\t(\t)\ninput:"); } int RtOpe(char **pKey, char *pIn)//判断输入的操作符或者功能
{
int i;
for(i=; i<; i++)
{
if(strcmp(pKey[i], pIn) == )
{
return i;
}
}
return -;
} int Check(char *pFormula)//判断表达式是否合格
{
int i=;
int flag=;
while(*(pFormula+i) != '\0')
{
if((*(pFormula+i) >= '' && *(pFormula+i) <= '') || *(pFormula+i) == '+' || *(pFormula+i) == '-'
|| *(pFormula+i) == '*' || *(pFormula+i) == '/' || *(pFormula+i) == '('
|| *(pFormula+i) == ')' || *(pFormula+i) == '.')
{
if(*(pFormula+i) == '(')
{
flag++;
}
else if(*(pFormula+i) == ')')
{
flag--;
}
}
else
{
printf("\nError formula !\n");
return ;
}
i++;
}
if(flag != )
{
printf("\nthe number '(',')' is wrong !\n");
return ;
}
else
{
return ;
}
} int InitStack(struct Stack *S)//初始化栈
{
S->base=(struct SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
if(S->base == NULL)
{
printf("\nMemory allocation failure !\n");
return -;
}
S->top=S->base;
S->size=STACK_SIZE;
return ;
} int DestroyStack(struct Stack *S)//销毁栈
{
free(S->base);
return ;
} int ClearStack(struct Stack *S)//清除栈
{
S->top=S->base;
return ;
} int GetTop(struct Stack S, struct SNode *Elem)//取出栈顶结点并返回节点值
{
if(S.top == S.base)
{
printf("Stack is empty !");
return -;
}
*Elem=*(S.top-);
return ;
} int Push(struct Stack *S, struct SNode Elem)//入栈
{
if(((S->top)-(S->base)) >= S->size)
{
S->base=(struct SNode *)realloc(S->base,(S->size+APPEND_SIZE)*sizeof(struct SNode));
if(S->base == NULL)
{
printf("Memory allocation failure !");
return -;
}
S->top=S->base+S->size;
S->size+=APPEND_SIZE;
}
*(S->top)=Elem;
S->top++;
return ;
} int Pop(struct Stack *S, struct SNode *Elem)//出栈
{
if(S->top == S->base)
{
printf("Stack is empty !");
return -;
}
*Elem=*(S->top-);
S->top--;
return ;
} double Operate(double Numa, char Opr, double Numb)//计算Numa,Numb经过Opr运算后的结果
{
switch(Opr)
{
case '+':
return (Numa+Numb);
case '-':
return (Numa-Numb);
case '*':
return (Numa*Numb);
case '/':
{
if(Numb != )
{
return (Numa/Numb);
}
else
{
printf("\nDivide by zero !\n");
}
}
default :
return ;
}
} char Judge(struct SNode Popc, struct SNode Cr)//比较操作符优先级
{
char c;
int i,j;
char Prior[][] =
{
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=',' '},
{'>','>','>','>',' ','>','>'},
{'<','<','<','<','<',' ','='}
};// 算符间的优先关系
char Opt[]={'+','-','*','/','(',')','#'};
for(i=;i<;i++)
{
if(Popc.ch == Opt[i])
break;
}
for(j=;j<;j++)
{
if(Cr.ch == Opt[j])
break;
}
c=Prior[i][j];
return c;
} char *killzero(char *Str, double Result)//消除末尾的0
{
int i;
sprintf(Str,"%lf",Result);
i=strlen(Str)-;
while(i && (Str[i] == ''))
{
Str[i]='\0';
i--;
}
if(Str[i] == '.')
Str[i]='\0';
return Str;
} double Cal(char *pFormula)//计算表达式
{
struct Stack optr,opnd,*Poptr,*Popnd;
Poptr = &optr;
Popnd = &opnd; int i=,j=;
struct SNode Numa,Numb,Opr,Outopr,tem,result;
struct SNode *pNuma=&Numa;
struct SNode *pNumb=&Numb;
struct SNode *pOpr=&Opr; struct SNode *pOutopr=&Outopr;
struct SNode *presult=&result;
struct SNode *ptem=&tem;
result.data=; struct SNode xTem,TemResult,Data,Crtem; char Temp[]={'\0'},Cntem[];
char CpFormula[];
xTem.ch='#'; InitStack(Poptr); //运算符栈
Push(Poptr, xTem);
InitStack(Popnd); //数字栈
Check(pFormula); while(*(pFormula+j) != '\0')
{
CpFormula[j]=*(pFormula+j);
j++;
}
CpFormula[j]='\0';
strcat(CpFormula, "#");
printf("\n%s\n", CpFormula); while(CpFormula[i] != '\0')
{
if(((CpFormula[i] >= '') && (CpFormula[i] <= ''))||(CpFormula[i] == '.'))//当前为数字,或者.
{
Cntem[]=CpFormula[i];
Cntem[]='\0';
strcat(Temp, Cntem);
if((CpFormula[i+] == '+') || (CpFormula[i+] == '-')|| (CpFormula[i+] == '*')|| (CpFormula[i+] == '/')
|| (CpFormula[i+] == '(')|| (CpFormula[i+] == ')') || (CpFormula[i+] == '#'))
{
Data.data=(double)atof(Temp);
Push(Popnd, Data);
//printf("\nPush opnd\n");
strcpy(Temp, "\0");
}
i++;
}
else //当前为操作符
{
Crtem.ch=CpFormula[i];
GetTop(optr, ptem);
switch (Judge(tem, Crtem))
{
case '<': // 栈顶元素优先权低
{
Push(Poptr, Crtem);
//printf("\nPush optr\n");
i++;
break;
}
case '=': // 脱括号并接收下一字符
{
Pop(Poptr, pOutopr);
//printf("\nPop optr\n");
i++;
break;
}
case '>': // 退栈并将运算结果入栈
{
Pop(Poptr, pOpr);
Pop(Popnd, pNumb);
Pop(Popnd, pNuma);
TemResult.data=Operate(Numa.data, Opr.ch, Numb.data);
//printf("\n> %.4f\n",y.data); Push(Popnd, TemResult);
break;
}
default:
{
printf("\nError !\n");
break;
}
}
}
} Pop(Popnd, presult);
DestroyStack(Poptr);
DestroyStack(Popnd);
//printf("\n%.4f\n",result.data);*/
return result.data;
}

基于c的简易计算器二的更多相关文章

  1. 基于Andriod的简易计算器

    这学期有安卓这门课,这里做了一个简易的计算器,实现了两位数加减乘除的基本功能,比较简单适合用来入门学习. 运行效果 预备知识 实现这个计算器之前要先了解实现计算器需要的基本组件 1.TextView ...

  2. 基于c的简易计算器一

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <malloc.h&g ...

  3. 基于java的简易计算器实现

    方法: 1.将string类型的表达式输入转换成后缀表达式 2.计算后缀表达式 步骤一:将string类型的表达式输入转换成后缀表达式 输入字符串表达式,并将表达式转换成char型数组 String ...

  4. 制作一个简易计算器——基于Android Studio实现

    一个计算器Android程序的源码部分分为主干和细节两部分. 一.主干 1. 主干的构成 计算器的布局 事件(即计算器上的按钮.文本框)监听 实现计算 2. 详细解释 假设我们的项目名为Calcula ...

  5. Python之实现一个简易计算器

    自己动手写计算器 一.功能分析 用户输入一个类似这样 3*( 4+ 50 )-(( 100 + 40 )*5/2- 3*2* 2/4+9)*((( 3 + 4)-4)-4) 这样的表达式,假设表达式里 ...

  6. C#Windows Form简易计算器实现(中)

    昨天花了一天的时间弄计算器.也算是做出来了,还是简易的(怀疑猿生!!).在此先感谢昨天被我骚扰的朋友. 先贴一张界面看看 其实健壮性还是挺差的,用户体验也是极差的.比如说用户输入了不合理运算式子,我就 ...

  7. JavaScript简易计算器

    JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标 ...

  8. 微信小程序-简易计算器

    代码地址如下:http://www.demodashi.com/demo/14210.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...

  9. Qt、C++ 简易计算器

    Qt.C++实现简易计算器: 以下内容是我实现这个简易计算器整个过程,其中包括我对如何实现这个功能的思考.中途遇到的问题.走过的弯路 整个实现从易到难,计算器功能从简单到复杂,最开始设计的整个实现步骤 ...

随机推荐

  1. Json对象与Json字符串的转化、JSON字符串与Java对象的转换(转)

    一.Json对象与Json字符串的转化 1.jQuery插件支持的转换方式: $.parseJSON( jsonstr ); //jQuery.parseJSON(jsonstr),可以将json字符 ...

  2. Docker创建容器

    容器是镜像的一个运行实例,是基于镜像运行的轻量级环境,是一个或者一组应用. 怎样创建容器?将容器所基于的镜像名称传入即可,Docker会从本地仓库中寻找该镜像,如果本地仓库没有,则会自动从远程仓库中拉 ...

  3. Appium安卓与环境配置

    下载与安装: Appium-desktop项目地址:https://github.com/appium/appium-desktop 下载地址:https://github.com/appium/ap ...

  4. SpringBoot实现监听redis key失效事件

    需求: 处理订单过期自动取消,比如下单30分钟未支付自动更改订单状态 解决方案1: 可以利用redis天然的key自动过期机制,下单时将订单id写入redis,过期时间30分钟,30分钟后检查订单状态 ...

  5. Unity特殊文件夹详解

    ##1.Editor Editor文件夹可以在根目录下,也可以在子目录里,只要名子叫Editor就可以.比如目录:/xxx/xxx/Editor 和 /Editor 是一样的,无论多少个叫Editor ...

  6. NO--15 微信小程序,scroll-view选项卡和跳转

    大多数的商城类小程序都有这个功能,点击“全部订单”,“待付款”,“待发货”,“待收货”,“已完成”,会跳转页面且跳至与之相对应的选项卡中.所以我们在开发该小程序时也做了相同的功能.如下图:   scr ...

  7. 如何把word ppt 思维导图这类文件转化为高清晰度的图片(要干货只看粗体黑字)

    我使用思维导图做学习笔记,最终绘制了一张比较满意的思维导图,想要分享出去,但由于现在思维导图软件众多,成品文件格式差别蛮大,不利于传播和打开,所以需要转化为普通图片,但笔者使用的导图软件导出转化成的图 ...

  8. awk之close函数

    echo "21 2 " | awk '{ first[NR]=$ second[NR]=$ }END{ print "======打印第1列并排序:========== ...

  9. ssh软件及命令的使用

    常用软件安装及使用目录 第1章 ssh常用用法小结 1.1 连接到远程主机: 命令格式 : ssh name@remoteserver 或者 ssh remoteserver -l name 说明:以 ...

  10. 如何在静态方法或非Spring Bean中注入Spring Bean

           在项目中有时需要根据需要在自己new一个对象,或者在某些util方法或属性中获取Spring Bean对象,从而完成某些工作,但是由于自己new的对象和util方法并不是受Spring所 ...