📄 jisuan.cpp
字号:
#include <ctype.h> //引用头文件
#include <string.h>
#include "stdio.h"
#define N 50 //宏定义堆栈长度为50
typedef struct{ //定义存放操作数的堆栈段NumStack
int top; //存放栈顶元素的下标位置
double array[N];//栈元素的数组
}NumStack;
typedef struct{ //定义存放操作符号的堆栈段OpStack
int top;
char array[N];
}OpStack;
int Cint(char mychar){ //将字符转化为相应整数0==48(ASCII)
return (mychar-48);
}
void PushNum(NumStack *numstack,double num){ //操作数进栈
numstack->top++; //进栈栈顶自加1将新操作数置于栈顶
numstack->array[numstack->top-1]=num;
}
void PopNum(NumStack *numstack,double *num){ //操作数出栈
*num=numstack->array[numstack->top-1];
numstack->top--; //计算操作数num得到栈顶元素栈顶自减1
}
void PushOp(OpStack *opstack,char op){ //操作符号进栈
opstack->top++;
opstack->array[opstack->top-1]=op;
}
void PopOp(OpStack *opstack,char *op){ //操作符号出栈
*op=opstack->array[opstack->top-1];
opstack->top--;
}
double Calculator(double a,double b,char c) //计算函数
{ //a,b为操作数,c为操作符号
double result;
switch(c) //选择运算种类
{
case '+':result=a+b;break;
case '-':result=a-b;break;
case '*':result=a*b;break;
case '/':result=a/b;break;
}
return result; //返回计算结果result
}
char Priority(char y,char x) //判断比较符号优先级
{
char priority='<'; //默认x优先级高
switch(x)
{
case '+': //输入为+或-且栈顶为(或#时,输入x的优先级高
case '-':if(y=='(' || y=='#')priority='>';break;
case '*': //输入为*或/且栈顶为(或#或+或-时,输入x的优先级高
case '/':if(y=='(' || y=='#'|| y=='+' || y=='-')priority='>';break;
case '(':priority='>';break; //输入为(时为高优先级
case ')':if(y=='(')priority='=';break; //输入)时括号配对优先级相等
case '#':if(y=='#')priority='=';break; //结束符与栈顶开始符配对
default:priority='?'; //错误输入
}
return priority;
}
void Process(NumStack *numstack,OpStack *opstack,char x)//处理表达式的主体函数
{
double a,b;char c; //定义存放出栈的操作数和操作符
static double tempnum=0; //对数据进行生成时使用
static int len=10; //定义作为权值使用
static int dot=0,flags=0; //小数点和数据、符号进栈标志位
if(isdigit(x) || x=='.') //如果x是数字或小数点则继续即控制操作数的输入输出
{
if(x=='.') dot=1; //如果x是小数点就把小数点标志置1
else //如果x是数字则进入下面函数
{
if(dot==0) //如果当前还没有接受过小数点
tempnum=tempnum*10+Cint(x); //生成整数部分
else //如果当前已经接受过小数点
{
tempnum=tempnum+(double)Cint(x)/len; //生成小数部分
len=len*10; //每输入一位小数执行一次为下一次小数输入的权值
}
}
}
else //如果x不是数字或小数点时
{
if(flags==0 && x!='(') //flags=0时允许进栈,符号栈顶为(时不允许符号再数字进栈之前进栈
{PushNum(numstack,tempnum);tempnum=0;len=10;dot=0;}//操作数进栈还原变量
switch(Priority(opstack->array[opstack->top-1],x))
{ //调用Priority函数判断x与前一个操作符优先级选择操作
case '>':PushOp(opstack,x);flags=0;break;//高于前一个操作符则进栈
case '<':PopOp(opstack,&c); //低于前一个操作符则将栈顶的操作符操作数出栈
PopNum(numstack,&b);
PopNum(numstack,&a);
PushNum(numstack,Calculator(a,b,c));flags=1;//完成高优先级的数学计算再压入栈
Process(numstack,opstack,x);break; //继续输入数字或符号
case '=':PopOp(opstack,&c);flags=1;break; //优先级相等操作符出栈
default:printf("错误表达式输入!!");return; //其它情况提示错误并结束操作
}
}
}
void main() //主调用函数
{
NumStack numstack;OpStack opstack;char s[N];int i=0;//定义数字栈、字符栈、数组等变量
numstack.top=0;opstack.top=0; //将0存于两栈顶
PushOp(&opstack,'#'); //将#存放于操作符号的栈底
printf("\n请输入表达式以#结束并回车:");
scanf("%s",s); //输入表达式
for(i=0;i<strlen(s);i++) //循环i次处理长度为i的表达式(地址传递)
Process(&numstack,&opstack,s[i]);
printf("\n表达式的结果时: %f\n",numstack.array[numstack.top-1]);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -