C语言逆波兰表达式计算(后缀表达式计算器)

刚开始学习c语言时,我们都学过输入一个数在输入一个操作数在输入要进行的计算方式,在输入另一个操作数,然后通过内置的+ - / 以及内置头文件 *math.h等操作进行计算
但是我们可不可以直接输入我们熟悉的算式才得出结果呢,答案是肯定的,我博客上一篇介绍了C语言把中缀表达式转换为后缀表达式有兴趣的读者可以去看看,有了上篇的知识,在加上本篇的内容就可以很容易做出一个中缀表达式计算器了有兴趣的读者可以看完本文去尝试一下,对自己的能力也是一种提升

开始

添加适当的头文件,定义一个栈数据结构,

和之前一样,这里还是需要添加头文件和定义栈的数据结构,所有的操作都是基于栈的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14

#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;

创建一个栈

1
2
3
4
5
6
7
8
9
10

void (SqStack *s) {
s->base = (ElemType *)malloc(sizeof(ElemType));
if (!s->base)
{
exit(0);
}
s->top = s->base; //最开始 栈底就是栈顶
s->stackSize = STACK_INIT_SIZE;
}

入栈操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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++;
}

出栈操作

1
2
3
4
5
6
7
void Pop(SqStack *s, ElemType *e) {
if (s->top == s->base)
{
return;
}
*e = *--(s->top);
}

计算栈的当前容量(最大容量是s.stackSize)

1
2
3
int StackLen(SqStack s) {
return (s.top - s.base);
}

主函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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] = '';
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("最终的计算结果为%lfn", d);
return 0;
}

运行结果

本人用的是vs2015编译器,所以文中的scanf用了更安全的scanf_s, 如有引用 请自行替换成和自己的编译器想匹配的函数

cmd 运行结果
代码依然很简单,都是一些简单的指针操作,如果看不懂,请复习c语言的指针部分(其实指针搞清楚地址与值得对应关系就可以了)

函数形参 主函数中参数使用 函数中参数使用
*l &l l->next
l l l.next

注:

  • 上述代码在visual studio 2015中编译成功运行,其他ide请自行测试
  • 上述文字皆为个人看法,如有错误或建议请及时联系我