作者:Dongzhuo Chen
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define MAXSIZE 100
char valid_op[] = "+-*/";//定义合法的运算符数组,方便调用相应运算功能
char opStack[MAXSIZE];//定义运算符栈,用于存放暂时不用的运算符
int opTop = -1;
double numStack[MAXSIZE];//定义数栈,用于存放暂时不用的数
int numTop = -1;
void push_op(char op);
char pop_op();
void push_num(double num);
double pop_num();
int read();//定义读入函数
double num_temp;//暂时存放读到的数字
char op_temp;//暂时存放独到的运算符
int is_num, is_op;
//定义函数指针,调用相应运算功能
double add(double x, double y);
double sub(double x, double y);
double mul(double x, double y);
double divid(double x, double y);
double (*func[])(double x, double y) = {add, sub, mul, divid};
//定义优先级函数,用于判断左侧运算符与右侧运算符优先级
int prio_l(char op);
int prio_r(char op);
//定义储存表达式的数组
char s[MAXSIZE];
//定义pt变量,用于指示目前表达式读取进度
int pt = 0;
double num1, num2;
char op0;
int main()
{
int i, op_loc;
("请输入一个表达式(目前仅支持正数的加减乘除,可以使用括号),以#开头,并以#结束:\n");
printf("%s", s);
scanf();
read(op_temp);//读到第一个“#”,并将其存入运算符栈
push_op();
readwhile(true)
{
if(is_num == 1)//如果读到的是数字,将其存入数栈
{
(num_temp);
push_num}
if(is_op == 1)//如果读到的是运算符,判断其与运算符栈顶符号的优先级
{
if(prio_l(opStack[opTop]) < prio_r(op_temp))//若读到的运算符优先级较高,将其存入运算符栈
{
(op_temp);
push_op}
else if(prio_l(opStack[opTop]) == prio_r(op_temp))//若读到的运算符优先级相等,说明左右括号相遇,去括号
{
();
pop_op}
else if(prio_l(opStack[opTop]) > prio_r(op_temp))//若读到的运算符优先级较低,则先进行运算符栈顶的运算符运算
{
= pop_num();
num2 = pop_num();
num1 = pop_op();
op0 for(i = 0; i < 4; i ++)
{
if(op0 == valid_op[i])
{
= i;
op_loc break;
}
}
= (*func[op_loc])(num1,num2);
num_temp (num_temp);//将得到的结果存入数栈中
push_num--;
pt }
}
if(is_num==0 && op_temp=='#' && opStack[opTop]=='#')//两个#相遇时标志着运算结束
{
break;
}
();//读取下一个字符
read}
("这个表达式的结果是%f\n", numStack[numTop]);
printf("pause");
systemreturn 0;
}
int read()
{
if(s[pt] >= '0' && s[pt] <= '9')//如果读到的是数字 ,把读到的数字字符转换成对应的数值
{
= 1;
is_num = 0;
is_op double a = 0;
int t = 10;
while(s[pt] >= '0' && s[pt] <= '9')//处理小数点以前的位数
{
= 10 * a + s[pt] - '0';
a ++;
pt }
if(s[pt] == '.')
{
++;
pt }
while(s[pt] >= '0' && s[pt] <= '9')//处理小数点以后的位数
{
= a + (s[pt] - '0')*1.0/t;
a ++;
pt *= 10;
t }
= a;
num_temp return 0;
}
else//如果读到的是运算符
{
= 1;
is_op = 0;
is_num = s[pt];
op_temp ++;
pt return 0;
}
}
void push_op(char op)
{
if(opTop == MAXSIZE-1)
{
("operator stack is full!\n");
printf(0);
assert}
else
{
++;
opTop [opTop]=op;
opStack}
}
char pop_op()
{
char op;
if(opTop == -1)
{
("operator stack is empty!\n");
printf(0);
assert}
else
{
= opStack[opTop];
op --;
opTop }
return op;
}
void push_num(double num)
{
if(numTop == MAXSIZE)
{
("number stack is full!\n");
printf(0);
assert}
else
{
++;
numTop [numTop]=num;
numStack}
}
double pop_num()
{
double num;
if(numTop == -1)
{
("number stack is empty!\n");
printf(0);
assert}
else
{
= numStack[numTop];
num --;
numTop }
return num;
}
int prio_l(char op)
{
int prio;
switch(op)
{
case'+':
case'-':
= 4;
prio break;
case'#':
= 0;
prio break;
case'*':
case'/':
= 6;
prio break;
case'(':
= 2;
prio break;
case')':
= 7;
prio break;
}
return prio;
}
int prio_r(char op)
{
int prio;
switch(op)
{
case'+':
case'-':
= 3;
prio break;
case'#':
= 0;
prio break;
case'*':
case'/':
= 5;
prio break;
case'(':
= 7;
prio break;
case')':
= 2;
prio break;
}
return prio;
}
double add(double x, double y)
{
double ret = 0;
= x + y;
ret return ret;
}
double sub(double x, double y)
{
double ret = 0;
= x - y;
retreturn ret;
}
double mul(double x, double y)
{
double ret = 0;
= x * y;
ret return ret;
}
double divid(double x, double y)
{
double ret = 0;
= x / y;
retreturn ret;
}
欢迎来到adydio的个人博客网站!
建站的初衷是激发我持续学习的动力。撰写博客就好像总结自己的所得,我也好在写的过程中看看自己这一天到底学到了一些什么,一定程度上可以防止虚无度日吧。还有一个目的就是把这里当做树洞,记录自己的一些情绪变化,可以当一个乐子哈。
下面开始写一些正经一点的站点介绍。
建立个人博客我参考了b站的视频,及其对应博文。在主题的选取上借用了tangyuxian的hexo-theme-tangyuxian主题,我觉得非常棒!在此感谢上述作者和up主,我作为前端小白能凭兴趣搭建好这个网站离不开这些视频和博文的帮助。
建立站点前前后后花了我快两天的时间,遇到了不少bug,好在之前有过写flask的一点点经验,这次哪怕没学过相关知识,照葫芦画瓢也能把网站打理的比较像样。框架用的是hexo,并且利用netlify进行了托管部署,再在阿里云上买了个三年期限的域名,大概就是这么个流程。中途用别的主题因为种种原因换了一个又一个,也失败过几次,最终用这个主题完成了部署。
点击右下角旋转的卡通图案即可给我发送消息!我将会在微信里收到提醒。
无需登录,当然了你可以在评论区上方的表格里留下你的信息。
欢迎来到adydio space!