#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. java基础解析系列(三)---HashMap

    java基础解析系列(三)---HashMap java基础解析系列 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)-- ...

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

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

  3. 基于Cocos2d-x-1.0.1的飞机大战游戏迁移到Cocos2d-x-3.0版本,并移植到Android平台成功运行

    一.版本迁移中的问题 1.游戏元素Sprite.Label.Action等等的创建函数名都改为create. 2.函数的回调callfunc_selectorcallfuncN_selectorcal ...

  4. 【LeetCode算法题库】Day7:Remove Nth Node From End of List & Valid Parentheses & Merge Two Lists

    [Q19] Given a linked list, remove the n-th node from the end of list and return its head. Example: G ...

  5. 火狐插件安装-基于web自动化测试

    一.Firebug 安装 1.  打开火狐浏览器—选择右上角“打开菜单”(图一)----附件组件(图二) 图一 图二 2.  点击:扩展(图三)—-------用于所有附加组件的工具(图四)----选 ...

  6. java浮点数存储

    转自: [解惑]剖析float型的内存存储和精度丢失问题 1.小数的二进制表示问题 首先我们要搞清楚下面两个问题: (1)  十进制整数如何转化为二进制数 算法很简单.举个例子,11表示成二进制数: ...

  7. Flask之笔记集合

    目录 一.简述 二.基本使用 三.配置文件 四.路由系统 2.自定义正则路由 五.模版语言 六.请求和响应 七.Session 2.自定义session 八.蓝图 九.message 十.中间件 十一 ...

  8. 基于Promise规范的fetch API的使用

    基于Promise规范的fetch API的使用 fetch的使用 作用:fetch 这个API,是专门用来发起Ajax请求的: fetch 是由原生 JS 提供的 API ,专门用来取代 XHR 这 ...

  9. Teamproject Week7 --Scrum Meeting #1 2014.10.28

    这是团队的第一次会议,具体议题如下: 1)我们明确了团队成员的职责所需: PM职责:根据项目范围.质量.时间与成本的综合因素的考虑,进行项目的总体规划与阶段计划.  控制项目组各成员的工作进度,即时了 ...

  10. VS2010+WinXP+MFC程序 无法定位程序输入点于动态链接库

    1.问题描述 原开发环境:Win7 64位旗舰版,VS2010,ThinkPad T460 出现问题:自己开发的MFC程序在WinXP环境下无法正常运行,弹框“无法定位程序输入点InitializeC ...