C++利用堆栈实现算术表达式的求值，能够处理单目运算符，VS2017,程序异常就终止了，求教

# stack.h

`````` #ifndef STACK
#define STACK
#include "stdafx.h"
#include <cstdlib>

typedef struct stack {
double data;
struct stack *next;
}stack;

stack *init_stack()
{
stack *top;
top = (stack*)malloc(sizeof(stack));
top->next = NULL;
}

int isEmpty(stack *top)
{
if (top->next = NULL)
return 1;
else
return 0;
}
float push(stack *top, float x)
{
stack *p;
p = (stack*)malloc(sizeof(stack));
if (p == NULL)
return -1;
p->data = x;
p->next = top->next;
top->next = p;
return 0;
}

float pop(stack *top, float *x)
{
stack *p;
if (top->next == NULL)
return -1;
p = top->next;
*x = p->data;
top->next = p->next;
free(p);
return 0;
}

float getTop(stack *top)
{
float *x = NULL;
if (top->next == NULL)
return -1;
*x = top->next->data;
return *x;
}

#endif // !STACK
``````

****## 算术表达式求值.cpp****

#include "stdafx.h"
#include
#include
#include "stack2.h"
#include
using namespace std;
class Calculator {
private:
stack *opnd;
stack *optr;

public:
Calculator();
virtual ~Calculator();
int getnext(int *n);
int getIndex(char a);
char operPrior(char a, char b);
float operation(float a, float operate, float b);
float evaluateEpression();
};

Calculator::Calculator() {
opnd = init_stack();
optr = init_stack();
}

Calculator::~Calculator() {
;
}

int Calculator::getnext(int n) {
char c;
*n = 0;
while ((c = getchar()) == ' ');
if ((!isdigit(c)) && (c != '+' || c != '-' || c != '
' || c != '/' || c != '(' || c != ')' || c != '='))
{
throw ("表达式出错！");
}
else
{
push(optr, c);
n = c;
return 1;
}
do {
*n = *n * 10 + (c - '0');
c = getchar();
} while(isdigit(c));
cin.putback(c);
return 0;
}
int Calculator::getIndex(char a)
{
int i;
switch (a)
{
case '+':
i = 0; break;
case '-':
i = 1; break;
case '
':
i = 2; break;
case '/':
i = 3; break;
case '(':
i = 4; break;
case ')':
i = 5; break;
case '=':
i = 6; break;
default:
break;
}
return i;
}
char Calculator::operPrior(char a, char b)
{
int i = getIndex(a);
int j = getIndex(b);
char pre[7][7] = {
{ '>','>','<','<','<','>','>' },
{ '>','>','<','<','<','>','>' },
{ '>','>','>','>','<','>','>' },
{ '>','>','>','>','<','>','>' },
{ '<','<','<','<','<','=','0' },
{ '>','>','>','>','0','>','>' },
{ '<','<','<','<','<','0','=' }
};
return pre[i][j];
}
float Calculator::operation(float a, float operate, float b)
{
float result = 0.0;
switch ((int)operate)
{
case '+':
result = a + b; break;
case '-':
result = a - b; break;
case'*':
result = a * b; break;
case '/':
result = a / b; break;
default:
break;
}
return result;
}
float Calculator::evaluateEpression()
{
int flag = 0;
char priorChar;
int ch;
float *x = NULL;
char prior;
float left, right;
float operate;
float *top;
push(optr, '=');
priorChar = '=';
flag = getnext(&ch);
while (getTop(optr) != '=' || ch != '=')
{
if (!flag)
{
push(opnd, ch);
priorChar = '0';
flag = getnext(&ch);
}
else
{
priorChar = ch;
if ((priorChar == '=' || priorChar == '(') && (ch == '+' || ch == '-'))
{
push(opnd, 0);
priorChar = '0';
}
prior = operPrior(getTop(optr), ch);
switch (prior)
{
case '<':
push(optr, ch);
flag = getnext(&ch);
break;
case '>':
if (isEmpty(opnd))
throw ("表达式出错！");
pop(opnd, &right);
if (isEmpty(opnd))
throw ("表达式出错！");
pop(opnd, &left);
pop(optr, &operate);
push(opnd, operation(left, operate, right));
flag = getnext(&ch);
break;
case '=':
pop(optr, &operate);
flag = getnext(&ch);
break;
case '0':
throw ("表达式出错！");
break;
default:
break;
}
}
}
pop(opnd, x);
return *x;
}
int main()
{
Calculator calcuExpression;
float result = 0.0;
result = calcuExpression.evaluateEpression();
cout << result << endl;
return 0;
}

1个回答

C++利用堆栈实现算术表达式的求值，能够处理单目运算符，VS2017,程序异常就终止了，求教
# **stack.h** ``` #ifndef STACK #define STACK #include "stdafx.h" #include <cstdlib> typedef struct stack { double data; struct stack *next; }stack; stack *init_stack() { stack *top; top = (stack*)malloc(sizeof(stack)); top->next = NULL; return top; } int isEmpty(stack *top) { if (top->next = NULL) return 1; else return 0; } float push(stack *top, float x) { stack *p; p = (stack*)malloc(sizeof(stack)); if (p == NULL) return -1; p->data = x; p->next = top->next; top->next = p; return 0; } float pop(stack *top, float *x) { stack *p; if (top->next == NULL) return -1; p = top->next; *x = p->data; top->next = p->next; free(p); return 0; } float getTop(stack *top) { float *x = NULL; if (top->next == NULL) return -1; *x = top->next->data; return *x; } #endif // !STACK ``` ****## 算术表达式求值.cpp**** #include "stdafx.h" #include <stdlib.h> #include <ctype.h> #include "stack2.h" #include <iostream> using namespace std; class Calculator { private: stack *opnd; stack *optr; public: Calculator(); virtual ~Calculator(); int getnext(int *n); int getIndex(char a); char operPrior(char a, char b); float operation(float a, float operate, float b); float evaluateEpression(); }; Calculator::Calculator() { opnd = init_stack(); optr = init_stack(); } Calculator::~Calculator() { ; } int Calculator::getnext(int *n) { char c; *n = 0; while ((c = getchar()) == ' '); if ((!isdigit(c)) && (c != '+' || c != '-' || c != '*' || c != '/' || c != '(' || c != ')' || c != '=')) { throw ("表达式出错！"); } else { push(optr, c); *n = c; return 1; } do { *n = *n * 10 + (c - '0'); c = getchar(); } while(isdigit(c)); cin.putback(c); return 0; } int Calculator::getIndex(char a) { int i; switch (a) { case '+': i = 0; break; case '-': i = 1; break; case '*': i = 2; break; case '/': i = 3; break; case '(': i = 4; break; case ')': i = 5; break; case '=': i = 6; break; default: break; } return i; } char Calculator::operPrior(char a, char b) { int i = getIndex(a); int j = getIndex(b); char pre[7][7] = { { '>','>','<','<','<','>','>' }, { '>','>','<','<','<','>','>' }, { '>','>','>','>','<','>','>' }, { '>','>','>','>','<','>','>' }, { '<','<','<','<','<','=','0' }, { '>','>','>','>','0','>','>' }, { '<','<','<','<','<','0','=' } }; return pre[i][j]; } float Calculator::operation(float a, float operate, float b) { float result = 0.0; switch ((int)operate) { case '+': result = a + b; break; case '-': result = a - b; break; case'*': result = a * b; break; case '/': result = a / b; break; default: break; } return result; } float Calculator::evaluateEpression() { int flag = 0; char priorChar; int ch; float *x = NULL; char prior; float left, right; float operate; float *top; push(optr, '='); priorChar = '='; flag = getnext(&ch); while (getTop(optr) != '=' || ch != '=') { if (!flag) { push(opnd, ch); priorChar = '0'; flag = getnext(&ch); } else { priorChar = ch; if ((priorChar == '=' || priorChar == '(') && (ch == '+' || ch == '-')) { push(opnd, 0); priorChar = '0'; } prior = operPrior(getTop(optr), ch); switch (prior) { case '<': push(optr, ch); flag = getnext(&ch); break; case '>': if (isEmpty(opnd)) throw ("表达式出错！"); pop(opnd, &right); if (isEmpty(opnd)) throw ("表达式出错！"); pop(opnd, &left); pop(optr, &operate); push(opnd, operation(left, operate, right)); flag = getnext(&ch); break; case '=': pop(optr, &operate); flag = getnext(&ch); break; case '0': throw ("表达式出错！"); break; default: break; } } } pop(opnd, x); return *x; } int main() { Calculator calcuExpression; float result = 0.0; result = calcuExpression.evaluateEpression(); cout << result << endl; return 0; }

20道你必须要背会的微服务面试题，面试一定会被问到

Windows可谓是大多数人的生产力工具，集娱乐办公于一体，虽然在程序员这个群体中都说苹果是信仰，但是大部分不都是从Windows过来的，而且现在依然有很多的程序员用Windows。 所以，今天我就把我私藏的Windows必装的软件分享给大家，如果有一个你没有用过甚至没有听过，那你就赚了????，这可都是提升你幸福感的高效率生产力工具哦！ 走起！???? NO、1 ScreenToGif 屏幕，摄像头和白板...

2020 年，大火的 Python 和 JavaScript 是否会被取而代之？
Python 和 JavaScript 是目前最火的两大编程语言，但是2020 年，什么编程语言将会取而代之呢？ 作者 |Richard Kenneth Eng 译者 |明明如月，责编 | 郭芮 出品 | CSDN（ID：CSDNnews） 以下为译文： Python 和 JavaScript 是目前最火的两大编程语言。然而，他们不可能永远屹立不倒。最终，必将像其他编程语言一...

Flutter 会不会被苹果限制其发展?

Idea 中最常用的10款插件（提高开发效率），一定要学会使用！

AI 没让人类失业，搞 AI 的人先失业了

2020年，冯唐49岁：我给20、30岁IT职场年轻人的建议

B站是个宝，谁用谁知道???? 作为一名大学生，你必须掌握的一项能力就是自学能力，很多看起来很牛X的人，你可以了解下，人家私底下一定是花大量的时间自学的，你可能会说，我也想学习啊，可是嘞，该学习啥嘞，不怕告诉你，互联网时代，最不缺的就是学习资源，最宝贵的是啥？ 你可能会说是时间，不，不是时间，而是你的注意力，懂了吧！ 那么，你说学习资源多，我咋不知道，那今天我就告诉你一个你必须知道的学习的地方，人称...

【蘑菇街技术部年会】程序员与女神共舞，鼻血再次没止住。（文末内推）

Linux必懂知识大总结（补）

Java校招入职华为，半年后我跑路了

Python全栈 Linux基础之3.Linux常用命令
Linux对文件（包括目录）有很多常用命令，可以加快开发效率：ls是列出当前目录下的文件列表，选项有-a、-l、-h，还可以使用通配符；c功能是跳转目录，可以使用相对路径和绝对路径；mkdir命令创建一个新的目录，有-p选项，rm删除文件或目录，有-f、-r选项；cp用于复制文件，有-i、-r选项，tree命令可以将目录结构显示出来（树状显示），有-d选项，mv用来移动文件/目录，有-i选项；cat查看文件内容，more分屏显示文件内容，grep搜索内容；>、>>将执行结果重定向到一个文件；|用于管道输出。
​两年前不知如何编写代码的我，现在是一名人工智能工程师

Python实战：抓肺炎疫情实时数据，画2019-nCoV疫情地图

loonggg读完需要5分钟速读仅需 2 分钟大家好，我是你们的校长。我知道大家在家里都憋坏了，大家可能相对于封闭在家里“坐月子”，更希望能够早日上班。今天我带着大家换个思路来聊一个问题...

&lt;!DOCTYPE html&gt; &lt;html lang="en"&gt; &lt;head&gt; &lt;meta charset="UTF-8"&gt; &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt; &lt;meta http-equiv="X...
Spring框架|JdbcTemplate介绍

B 站上有哪些很好的学习资源?

24岁的程序员，还在未来迷茫，不知道能不能买得起房子