刚开始学习c语言时,我们都学过输入一个数在输入一个操作数在输入要进行的计算方式,在输入另一个操作数,然后通过内置的+ - / 以及内置头文件 *math.h等操作进行计算 但是我们可不可以直接输入我们熟悉的算式才得出结果呢,答案是肯定的,我博客上一篇介绍了C语言把中缀表达式转换为后缀表达式有兴趣的读者可以去看看,有了上篇的知识,在加上本篇的内容就可以很容易做出一个中缀表达式计算器了有兴趣的读者可以看完本文去尝试一下,对自己的能力也是一种提升
和之前一样,这里还是需要添加头文件和定义栈的数据结构,所有的操作都是基于栈的操作
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef double ElemType;
typedef struct
{
ElemType *base;
ElemType *top;
int stackSize;
}SqStack;
//创建一个栈
void initStack(SqStack *s) {
s->base = (ElemType *)malloc(sizeof(ElemType));
if (!s->base)
{
exit(0);
}
s->top = s->base; //最开始 栈底就是栈顶
s->stackSize = STACK_INIT_SIZE;
}
void Push(SqStack *s, ElemType e) {
//如果栈满 追加空间
if (s->top - s->base >= s->stackSize)
{
s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
if (!s->base)
{
exit(0);
}
s->top = s->base + s->stackSize; //设置栈顶
s->stackSize = s->stackSize + STACKINCREMENT;
}
*(s->top) = e;
s->top++;
}
void Pop(SqStack *s, ElemType *e) {
if (s->top == s->base)
{
return;
}
*e = *--(s->top);
}
int StackLen(SqStack s) {
return (s.top - s.base);
}
int main() {
SqStack s;
char c;
double d, e;
char str[100];
int i = 0;
initStack(&s);
printf("请按逆波兰表达式输入计算机数据,数据与运算符中间用空格隔开,以#结束\n");
scanf_s("%c", &c);
while (c != '#')
{
while (isdigit(c) || c=='.') //字符是否是数字
{
str[i++] = c;
str[i] = '\0';
scanf_s("%c", &c);
if (c==' ')
{
d = atof(str); //将字符串转换成浮点型
Push(&s, d);
i = 0;
break;
}
}
switch (c)
{
case '+':
Pop(&s, &e);
Pop(&s, &d);
Push(&s, d + e);
break;
case '-':
Pop(&s, &e);
Pop(&s, &d);
Push(&s, d - e);
break;
case '*':
Pop(&s, &e);
Pop(&s, &d);
Push(&s, d * e);
break;
case '/':
Pop(&s, &e);
Pop(&s, &d);
if (e != 0)
{
Push(&s, d / e);
}
else {
printf("除数为0,错误");
return -1;
}
break;
default:
break;
}
scanf_s("%c", &c);
}
Pop(&s, &d);
printf("最终的计算结果为%lf\n", d);
return 0;
}
本人用的是vs2015编译器,所以文中的scanf用了更安全的scanf_s, 如有引用 请自行替换成和自己的编译器想匹配的函数 代码依然很简单,都是一些简单的指针操作,如果看不懂,请复习c语言的指针部分(其实指针搞清楚地址与值得对应关系就可以了)
函数形参 | 主函数中参数使用 | 函数中参数使用 |
---|---|---|
*l | &l | l->next |
l | l | l.next |
注: