基于c的简易计算器二
#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的简易计算器二的更多相关文章
- 基于Andriod的简易计算器
这学期有安卓这门课,这里做了一个简易的计算器,实现了两位数加减乘除的基本功能,比较简单适合用来入门学习. 运行效果 预备知识 实现这个计算器之前要先了解实现计算器需要的基本组件 1.TextView ...
- 基于c的简易计算器一
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <malloc.h&g ...
- 基于java的简易计算器实现
方法: 1.将string类型的表达式输入转换成后缀表达式 2.计算后缀表达式 步骤一:将string类型的表达式输入转换成后缀表达式 输入字符串表达式,并将表达式转换成char型数组 String ...
- 制作一个简易计算器——基于Android Studio实现
一个计算器Android程序的源码部分分为主干和细节两部分. 一.主干 1. 主干的构成 计算器的布局 事件(即计算器上的按钮.文本框)监听 实现计算 2. 详细解释 假设我们的项目名为Calcula ...
- Python之实现一个简易计算器
自己动手写计算器 一.功能分析 用户输入一个类似这样 3*( 4+ 50 )-(( 100 + 40 )*5/2- 3*2* 2/4+9)*((( 3 + 4)-4)-4) 这样的表达式,假设表达式里 ...
- C#Windows Form简易计算器实现(中)
昨天花了一天的时间弄计算器.也算是做出来了,还是简易的(怀疑猿生!!).在此先感谢昨天被我骚扰的朋友. 先贴一张界面看看 其实健壮性还是挺差的,用户体验也是极差的.比如说用户输入了不合理运算式子,我就 ...
- JavaScript简易计算器
JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标 ...
- 微信小程序-简易计算器
代码地址如下:http://www.demodashi.com/demo/14210.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...
- Qt、C++ 简易计算器
Qt.C++实现简易计算器: 以下内容是我实现这个简易计算器整个过程,其中包括我对如何实现这个功能的思考.中途遇到的问题.走过的弯路 整个实现从易到难,计算器功能从简单到复杂,最开始设计的整个实现步骤 ...
随机推荐
- Oracle10g 客户端安装与配置说明
1:百度文库 http://wenku.baidu.com/link?url=bA-FrFMaqxkoifwz-oiPeU5QmMVVJyy8rYDBryhTUCJywpkDS0VNJcObCIM8l ...
- 随机游走模型(RandomWalk Mobility)
随机游走模型由首先由爱因斯坦在1926年以数学方式描述.由于自然界中的许多实体会以不可预知的方式移动,因此随机游走模型用来描述这种不稳定的移动.在这种移动模型中,移动节点随机选择一个方向和速度来从当前 ...
- 我所理解的selenium之PO设计模式
下午,花了点时间来整理UI自动化设计,就把我所理解的PO设计模式项目结构脑图整理如下,有不对的地方还望多多包涵.谢谢
- netbeans 类重复 解决
Help -> About -> Cache directory 记录Cache directory目录 删除该目录下的所有文件 重启
- Spring中的数据库事物管理
Spring中的数据库事物管理 只要给方法加一个@Transactional注解就可以了 例如:
- 关于MySql数据库主键及索引的区别
一.什么是索引?索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里 ...
- k倍区间:前缀和
[蓝桥杯][2017年第八届真题]k倍区间 题目描述 给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列Ai, Ai+1, ... Aj(i <= j)之和是K的倍数 ...
- php学习--变量和数据类型
PHP变量 变量 程序执行期间,可以变化的量即为变量. 声明变量 以美元$ 符号声明 注意:(PHP严格区分大小写) 变量名称以 字母.或下划线开始,后面跟上数字/字母/下划线,不能包含特殊字符 ...
- Beta阶段基于NABCD评论作品
组名:杨老师粉丝群 组长:乔静玉 组员:吴奕瑶 刘佳瑞 公冶令鑫 杨磊 刘欣 张宇 卢帝同 一.拉格朗日2018--<飞词> 1.1.NABCD分析 N(Need,需求):该小 ...
- Daily Scrumming 2015.10.20(Day 1)
一.今明两天任务表 Member Today’s Task Tomorrow’s Task 江昊 购买服务器,搭建服务器,配置服务器端用户与权限管理 配置ruby与rails环境 配置mysql与数据 ...