利用堆栈实现计算器

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
#define END '\n'
char input_h = '\n';//定义全局变量,用于缓存输入慢速
char input_p = '\n';//定义全局变量,用于缓存输入
int temp = 0;//判断是否在完全入栈前进行运算
char optr[MAXSIZE];   //运算符栈
int  optrTop;        //运算符栈顶
double opnd[MAXSIZE];  //操作数栈
int  opndTop;         //操作数栈顶
void PushOptr(char x) { //运算符进栈
	if (optrTop == MAXSIZE - 1) {
		printf("运算符栈已满!上溢\n");
		exit(1);
	}
	else
	{
		optrTop++;
		optr[optrTop] = x;
	}
}
void PushOpnd(double x) { //操作数进栈
	if (opndTop == MAXSIZE - 1) {
		printf("操作数栈已满!上溢\n");
		exit(1);
	}
	else {
		opndTop++;
		opnd[opndTop] = x;
	}
}
char PopOptr() { //运算符出栈
	char y;
	if (optrTop == -1) {
		printf("输入有误\n");
		exit(1);
	}
	else {
		y = optr[optrTop];
		optrTop--;
	}
	return y;
}
double PopOpnd() { //操作数出栈
	double y;
	if (opndTop == -1) {
		printf("输入有误\n");
		exit(1);
	}
	else {
		y = opnd[opndTop];
		opndTop--;
	}
	return y;
}
char GetTopOptr() { //取出运算符栈顶元素
	if (optrTop != -1)
		return optr[optrTop];
	else {
		printf("输入有误\n");
		exit(1);
	}
}
double gettop_opnd() { //取出操作数栈顶元素
	if (opndTop != -1)
		return opnd[opndTop];
	else {
		printf("输入有误\n");
		exit(1);
	}
}
void inistack_optr() { //初始化运算符栈
	optrTop = -1;
}
void inistack_opnd() { //初始化操作数栈
	opndTop = -1;
}
char Precede(char t1, char t2) { //判断优先级
	char f;
	switch (t2) {
	case '+':
	case '-':
		if (t1 == '(' || t1 == END)
			f = '<';
		else
			f = '>';
		break;

	case '*':
	case '/':
		if (t1 == '*' || t1 == '/' || t1 == ')')
			f = '>';
		else
			f = '<';
		break;

	case '(':
		if (t1 == ')') {
			printf("输入有误\n");
			exit(1);
		}
		else
			f = '<';
		break;
	case ')':
		switch (t1) {
		case '(':
			f = '=';
			break;
		case END:
			printf("输入有误\n");
			exit(1);
		default:
			f = '>';
		}
		break;
	case END:
		switch (t1) {
		case END:
			f = '=';
			break;
		case '(':
			printf("输入有误\n");
			exit(1);
		default:
			f = '>';
		}
	}
	return f;
}

int char_In(char c) { //判断是否为运算符
	switch (c) {
	case '+':
	case '-':
		if ((!temp) && (char_In(input_h) || input_h == '\n')) {//检测上一个输入是否为操作符
			PushOpnd(0);//向操作数栈填入一个0参与负数运算
		}
		return 1;
	case '(':
		if ((!temp)) {
			if (input_h == ')' || (input_h >= '0' && input_h <= '9') || input_h == '.') {
				printf("输入有误\n");
				exit(0);
			}
		}
		return 1;
	case ')':
		if ((!temp)) {
			if (!((input_h >= '0' && input_h <= '9') || input_h == ')')) {
				printf("输入有误\n");
				exit(0);
			}
		}
		return 1;
	case '*':
	case '/':

	case END:
		return 1;

	default:
		return 0;
	}
}
double Operate(double a, char theta, double b) { //对出栈的两个数计算
	double c;
	switch (theta) { //运算符
	case '+':
		c = a + b; //输出0-9的ASCII码
		break;
	case '-':
		c = a - b;
		break;
	case '*':
		c = a * b;
		break;
	case '/':
		c = a / b;

	}
	return c;
}

double EvaluateExpression() {
	//使用运算符优先算法进行算术表示式求值
	int cache_Len = 0, i, flag = 0;//计算连续输入数字个数
	double a, b, curnum;//存储字符串转换成的小数
	char stack_x, theta, input_c, buff[MAXSIZE];//存储数字字符串
	inistack_optr();  //初始化运算符栈
	PushOptr(END);   //使结束符进栈
	inistack_opnd(); //初始化操作数栈
	input_c = getchar();//输入
	stack_x = GetTopOptr();
	while (input_c != END || stack_x != END) { //判断计算是否结束
		if (char_In(input_c)) { //若输入的字符是7种运算符之一
			input_h = input_c;//缓存上一个输入
			for (i = 0; i < flag; i++) {//缓存字符串置空
				buff[i] = '\0';
			}
			if (flag) {//将数字推向操作数栈
				PushOpnd(curnum);
			}
			flag = 0;//标志回滚【+】
			switch (Precede(stack_x, input_c)) {
			case '<':
				temp = 0;
				PushOptr(input_c); //若栈顶(x)优先级<输入则输入进栈
				input_c = getchar();
				break;
			case '=':
				temp = 0;
				stack_x = PopOptr();//相等则出栈
				input_c = getchar();
				break;

			case '>':
				temp++;
				theta = PopOptr();
				b = PopOpnd();
				a = PopOpnd();
				PushOpnd(Operate(a, theta, b));
				break;
			}

		}
		else if ((input_c >= '0' && input_c <= '9') || input_c == '.') { //input_c是操作数
			if (input_h == ')') {//输入检查)右边不能为数字 
				printf("输入有误\n");
				exit(0);
			}
			input_h = input_c;//缓存上一个输入
			flag++;//标志计数增加
			buff[flag - 1] = input_c;//输入的字符暂时存储到buff缓存字符串中
			curnum = (double)atof(buff);//将字符串转换为小数
			input_c = getchar();
		}
		else {
			printf("输入有误\n");
			exit(1);
		}
		stack_x = GetTopOptr();
	}
	return(gettop_opnd());
}
int main() {

	printf("请输入算术表达式,以回车结束\n");
	while (1) {
		printf("%f\n", EvaluateExpression());
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_52088967/article/details/124026860
今日推荐