基于c的简易计算器一
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <malloc.h> #define STACK_SIZE 100
#define APPEND_SIZE 10 struct SNode{
float data; /*存放操作数或者计算结果*/
char ch; /*存放运算符*/
}; struct Stack{
SNode *top;
SNode *base;
int size;
}; /*栈操作函数*/
int InitStack(Stack &S); /*创建栈*/
int DestroyStack(Stack &S); /*销毁栈*/
int ClearStack(Stack &S); /*清空栈*/
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
int Push(Stack &S,SNode e); /*将结点e压入栈*/
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ /*表达式计算器相关函数*/
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
float compute(); /*表达式结算器主函数*/
char *killzero(float result); /*去掉结果后面的0*/ int InitStack(Stack &S)
{
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
if(S.base==NULL)
{
printf("动态分配内存失败!");
return -;
}
S.top=S.base;
S.size=STACK_SIZE;
return ;
} int DestroyStack(Stack &S)
{
free(S.base);
return ;
} int ClearStack(Stack &S)
{
S.top=S.base;
return ;
} int GetTop(Stack S,SNode &e)
{
if(S.top==S.base)
{
printf("栈以为空!");
return -;
}
e=*(S.top-);
return ;
} int Push(Stack &S,SNode e)
{
if(S.top-S.base>=S.size)
{
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
if(S.base==NULL)
{
printf("动态分配内存失败!");
return -;
}
S.top=S.base+S.size;
S.size+=APPEND_SIZE;
}
*S.top=e;
S.top++;
return ;
} int Pop(Stack &S,SNode &e)
{
if(S.top==S.base)
{
printf("栈为空!");
return -;
}
e=*(S.top-);
S.top--;
return ;
} char get_precede(char s,char c)
{
switch(s)
{
case '+':
case '-':
if(c=='+'||c=='-')
return '>';
else if(c=='*'||c=='/')
return '<';
else if(c=='(')
return '<';
else if(c==')')
return '>';
else
return '>';
case '*':
case '/':
if(c=='+'||c=='-')
return '>';
else if(c=='*'||c=='/')
return '>';
else if(c=='(')
return '<';
else if(c==')')
return '>';
else
return '>';
case '(':
if(c=='+'||c=='-')
return '<';
else if(c=='*'||c=='/')
return '<';
else if(c=='(')
return '<';
else if(c==')')
return '=';
else
return 'E';
case ')':
if(c=='+'||c=='-')
return '>';
else if(c=='*'||c=='/')
return '>';
else if(c=='(')
return 'E';
else if(c==')')
return '>';
else
return '>';
case '#':
if(c=='+'||c=='-')
return '<';
else if(c=='*'||c=='/')
return '<';
else if(c=='(')
return '<';
else if(c==')')
return 'E';
else
return '=';
default:
break;
}
return ;
} int isOpr(char c)
{
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
return ;
else
return ;
} float operate(float x, char opr, float y)
{
float result;
switch (opr)
{
case '+':
result = x + y;
break;
case '-':
result = x - y;
break;
case '*':
result = x * y;
break;
case '/':
if (y == )
{
printf("Divided by zero!\n");
return ;
}
else
{
result = x / y;
break;
}
default:
printf("Bad Input.\n");
return ;
}
return result;
} float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
{
Stack optr,opnd;
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
char c;
char buf[];
int i=; InitStack(optr); /*用于寄存运算符*/
InitStack(opnd); /*用于寄存操作数和计算结果*/
memset(buf,,sizeof(buf)); printf("Enter your expression:"); opr_in.ch='#';
Push(optr,opr_in); /*'#'入栈*/
GetTop(optr,opr_top);
c=getchar();
while(c!='='||opr_top.ch!='#')
{
if(isOpr(c)!=) /*不是运算符则保存到buf中,以便得到操作数*/
{
buf[i]=c;
i++;
c=getchar();
}
else /*是运算符*/
{
buf[i]='\0';
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
{
opn_in.data=(float)atof(buf);
Push(opnd,opn_in);
printf("opnd入栈:[%f]\n",opn_in.data);
i=;
memset(buf,,sizeof(buf));
}
opr_in.ch=c;
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
{
case '<': /*优先级小于栈顶结点,则运算符入栈*/
Push(optr,opr_in);
printf("optr入栈:[%c]\n",opr_in.ch);
c=getchar();
break;
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
Pop(optr,e);
printf("optr出栈:去掉括号\n");
c=getchar();
break;
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
Pop(optr,opr_t);
printf("optr出栈:[%c]\n",opr_t.ch);
if(Pop(opnd,b)<)
{
printf("Bad Input!\n");
fflush(stdin);
return -;
}
printf("opnd出栈:[%f]\n",b.data);
if(Pop(opnd,a)<)
{
printf("Bad Input!\n");
fflush(stdin);
return -;
}
printf("opnd出栈:[%f]\n",a.data);
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
printf("结果入栈:[%f]\n",opn_tmp.data);
break;
}
}
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
}
GetTop(opnd,opn_tmp);
DestroyStack(optr);
DestroyStack(opnd);
return opn_tmp.data;
} char *killzero(char *res,float result)
{
int i; sprintf(res,"%f",result);
i=(int)strlen(res)-;
while(i&&res[i]=='')
{
res[i]='\0';
i--;
}
if(res[i]=='.')
res[i]='\0';
return res;
} int main()
{
char ch;
char res[];
float result;
while()
{
result=compute();
printf("\nThe result is:%s\n",killzero(res,result));
printf("Do you want to continue(y/n)?:") ;
getchar();
scanf("%c",&ch);
putchar(ch);
if(ch=='n'||ch=='N')
break;
else
system("cls");
}
return ;
}
基于c的简易计算器一的更多相关文章
- 基于Andriod的简易计算器
这学期有安卓这门课,这里做了一个简易的计算器,实现了两位数加减乘除的基本功能,比较简单适合用来入门学习. 运行效果 预备知识 实现这个计算器之前要先了解实现计算器需要的基本组件 1.TextView ...
- 基于c的简易计算器二
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> ...
- 基于java的简易计算器实现
方法: 1.将string类型的表达式输入转换成后缀表达式 2.计算后缀表达式 步骤一:将string类型的表达式输入转换成后缀表达式 输入字符串表达式,并将表达式转换成char型数组 String ...
- 制作一个简易计算器——基于Android Studio实现
一个计算器Android程序的源码部分分为主干和细节两部分. 一.主干 1. 主干的构成 计算器的布局 事件(即计算器上的按钮.文本框)监听 实现计算 2. 详细解释 假设我们的项目名为Calcula ...
- JavaScript简易计算器
JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标 ...
- 如何使用Java AWT 创建一个简易计算器
摘要:手把手教你使用 Java AWT 创建一个简易计算器. 本文分享自华为云社区<手把手教你使用 Java AWT 创建一个简易计算器>,作者:海拥 . 关于AWT AWT (抽象窗口工 ...
- 自制c#简易计算器
这是一个课堂作业,我觉得作为一个简易的计算器不需要态度复杂的东西,可能还有一些bug,有空再慢慢加强. using System;using System.Collections.Generic;us ...
- 剖析简易计算器带你入门微信小程序开发
写在前面,但是重点在后面 这是教程,也不是教程. 可以先看Demo的操作动图,看看是个什么玩意儿,GitHub地址(https://github.com/dunizb/wxapp-sCalc) 自从微 ...
- PHP学习笔记02——简易计算器
<!DOCTYPE html> <html> <head> <title>PHP简易计算器</title> </head> &l ...
随机推荐
- Jmeter+ant+jenkins接口自动化测试 平台搭建(二)
一.依赖文件配置 1.在ant目录C:\apache-ant-1.10.5下新建一个demo文件夹,并将jmeter测试脚本放在该文件夹中 2.将\apache-jmeter-3.3\extras下面 ...
- (2017)你最不建议使用的Python Web框架?
https://www.sohu.com/a/164042813_737973 挺有意思的 经过一周的Django学习,以及对比,最终选定了以Flask入手来学习Python web开发.
- python解释 yield 和 Generators(生成器)
yield 和 Generators(生成器) 转自:http://www.oschina.net/translate/improve-your-python-yield-and-generators ...
- jmeter阶梯加压线程组
添加阶梯加压线程组路径为鼠标捕获测试计划后,点击鼠标右键->添加->Threads(Users)->jp@gc – Stepping Thread Group(deprecated) ...
- birt 访问频繁报错Cannot create JDBC driver of class '' for connect URL 'null' java.sql.SQLException: No suitable driver
一般birt项目都是部署tomcat启动.这个问题大概率是因为没有配置JNDI数据源的原因. 参考链接: https://www.cnblogs.com/xdp-gacl/p/3951952.html
- SICP读书笔记 2.3
SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...
- day12生成器
迭代器 __iter__() 获取迭代器 __next__() 下一个 生成器 本质就是迭代器 两种方式写生成器 1. 生成器函数 2. 生成器表达式 生成器函数 函数内部有yield. yield返 ...
- ossec兼容的操作系统
OSSEC兼容以下操作系统和日志格式 操作系统 以下操作系统可安装OSSEC代理 l GNU/Linux (all distributions, including RHEL, Ubuntu, Sl ...
- [leetcode-921-Minimum Add to Make Parentheses Valid]
Given a string S of '(' and ')' parentheses, we add the minimum number of parentheses ( '(' or ')', ...
- Daily Scrumming* 2015.10.27(Day 8)
一.总体情况总结 今日项目总结: 前后端同一了API设计以及API权限认证.用户状态保存的开发方案 API以及后端模型已经开始开发,前端UEditor开始学习,本周任务有良好的起步 前后端完成分工,后 ...