#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的简易计算器一的更多相关文章

  1. 基于Andriod的简易计算器

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

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

    #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> ...

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

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

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

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

  5. JavaScript简易计算器

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

  6. 如何使用Java AWT 创建一个简易计算器

    摘要:手把手教你使用 Java AWT 创建一个简易计算器. 本文分享自华为云社区<手把手教你使用 Java AWT 创建一个简易计算器>,作者:海拥 . 关于AWT AWT (抽象窗口工 ...

  7. 自制c#简易计算器

    这是一个课堂作业,我觉得作为一个简易的计算器不需要态度复杂的东西,可能还有一些bug,有空再慢慢加强. using System;using System.Collections.Generic;us ...

  8. 剖析简易计算器带你入门微信小程序开发

    写在前面,但是重点在后面 这是教程,也不是教程. 可以先看Demo的操作动图,看看是个什么玩意儿,GitHub地址(https://github.com/dunizb/wxapp-sCalc) 自从微 ...

  9. PHP学习笔记02——简易计算器

    <!DOCTYPE html> <html> <head> <title>PHP简易计算器</title> </head> &l ...

随机推荐

  1. Spring学习(十七)----- Spring自动代理创建者

    1. BeanNameAutoProxyCreator示例 在此之前,必须手动创建一个代理bean(ProxyFactryBean). <beans xmlns="http://www ...

  2. Docker 创建虚拟机并且远程链接

    快读创建虚拟机 使用我编辑的镜像(688M) docker run -itd --name=test03 -p 5523:22 registry.cn-beijing.aliyuncs.com/act ...

  3. 利用Smith圆图设计匹配网络

    要实现射频最大的功率传输,必须使负载阻抗与源阻抗相匹配(即信号源阻抗与负载阻抗共轭相等),实现匹配的通常做法是在源和负载之间插入一个匹配网络,该网络不仅仅为减少功率损耗而设计,还可减少噪声干扰.提高功 ...

  4. Android Service(上)

    一 Service简介 Service是Context的子类 Service是四大组件之一 用来在后台处理一些比较耗时的操作或者去执行某些需要长期运行的任务 二 注意 Service里面不能直接执行耗 ...

  5. 比较undefined和“undefined”

    说实话,它们之间的区别挺明显的,我们一般认为undefined是JavaScript提供的一个“关键字”,而“undefined”却是一个字符串,只是引号的内容和undefined一样. undefi ...

  6. host命令详解

    基础命令学习目录首页 原文链接:https://blog.csdn.net/xin_y/article/details/53924763 分析域名查询工具,测试域名系统工作是否正常 语法: host ...

  7. time命令详情

    基础命令学习目录首页 原文链接:https://blog.csdn.net/adaptiver/article/details/6596143?utm_source=blogxgwz3 linux下t ...

  8. excel中如何将时间戳转换为日期格式

    https://www.cnblogs.com/xueluozhangxin/p/5868225.html =TEXT((B2/1000+8*3600)/86400+70*365+19,"y ...

  9. 奔跑吧DKY——团队Scrum冲刺阶段-Day 3

    今日完成任务 各个成员今日完成的任务(如果完成的任务为开发或测试任务,需给出对应的Github代码签入记录截图:如果完成的任务为调研任务,需给出对应的调研总结博客链接:如果完成的任务为学习技术任务,需 ...

  10. gogoing软件NABCD

    N,need 需求:gogoing项目目前打算做得是一个基于石家庄铁道大学在校大学生对于短期节假日出行旅游的指南.最关键的定义为“穷游”.“穷”则体现在以小的花销去实现最完美的旅游方式.我们的gogo ...