使用C语言与栈实现简单多则运算计算器(包括括号优先级运算)

#include <stdio.h>
#include <stdlib.h> 
#define MAX 20
//定义第一个栈---作为存放运算数的操作符 
struct SNode_Num
{
	int datas[MAX];
	int top;
};
typedef struct SNode_Num OperateNum;

//定义第二个栈---作为存放运算符号的栈 
struct SNode_Symbol
{
	char symbol[MAX];
	int top;
};
typedef struct SNode_Symbol OperateSymbol;

/********************************************************************
描述:定义函数:InitOperandNum,并且初始化运算数栈顶 
参数:OperateNum *StackNum
返回值:void
********************************************************************/
void InitOperateNum(OperateNum *StackNum)
{
	StackNum->top = -1; 
}

/********************************************************************
描述:定义函数: InitOperateSymbol,并且初始化运算符栈顶 
参数:OperateSymbol *StackSymbol
返回值:void
********************************************************************/
void InitOperateSymbol(OperateSymbol *StackSymbol)
{
	StackSymbol->top = -1;
} 

/********************************************************************
描述:定义函数:PushOperateNum, 压一个数到栈顶 
参数:OperateNum *StackNum, int x 
返回值:void 
********************************************************************/
void PushOperateNum(OperateNum *StackNum, int x)
{
	StackNum->top++;
	StackNum->datas[StackNum->top] = x; 
} 

/********************************************************************
描述:定义函数:PushOperateSymbol,压一个运算符到栈顶 
参数:OperateSymbol *StackSymbol, char ch
返回值:void 
********************************************************************/
void PushOperateSymbol(OperateSymbol *StackSymbol, char ch)
{
	StackSymbol->top++;
	StackSymbol->symbol[StackSymbol->top] = ch; 
}

/********************************************************************
描述:定义函数:PopOperateNum,将运算数从栈中读取出来 
参数:OperateNum *StackNum
返回值:返回取出来的数 
********************************************************************/
int PopOperateNum(OperateNum *StackNum)
{
	int num;
	num = StackNum->datas[StackNum->top];
	StackNum->top--;
	return num;
}

/********************************************************************
描述:定义函数:PopOperateSymbol,将运算符从栈中取出来 
参数:OperateSymbol *StackSymbol
返回值:返回取出来的符号 
********************************************************************/
char PopOperateSymbol(OperateSymbol *StackSymbol)
{
	char ch;
	ch = StackSymbol->symbol[StackSymbol->top];
	StackSymbol->top--;
	return ch;
}

//取出相应的数 
int GetOperateNum(OperateNum *StackNum)
{
	return StackNum->datas[StackNum->top];
}

//取出相应运算符 
char GetOperateSymbol(OperateSymbol *StackSymbol)
{
	return StackSymbol->symbol[StackSymbol->top]; 
} 

/********************************************************************
描述:定义函数, IsOperateSymbolOrNum,判断输入的符号是那些符号 
参数:char ch
返回值:有符号返回1,无符号返回0 
********************************************************************/
short IsOperateSymbolOrNum(char ch)
{
	//判断所有需要用的操作符 包括 + - * / ( ) \n 
	if(ch == '+' || ch == '-' || ch == '*' 
	|| ch == '/' || ch == '(' || ch == ')' || ch == '\n') return 1;
	
	else return 0;	
}

/********************************************************************
描述:定义函数: Priority,用于判断符号优先级运算 
参数:char inputnum, char ch
返回值:符号的大小的字符 
********************************************************************/
char Priority(char inputnum, char ch)
{
	switch(inputnum)
	{
		//加减在同一个优先级上 
		case '+':
		case '-':
		{
			if(ch == '+' || ch == '-') return '>';
			else if(ch == '*' || ch == '/') return '<';
			else if(ch == '(') return '<';
			else if(ch == ')') return '>';
			else return '>';	
		}
			break;
		
		//乘除在同一优先级 
		case '*':
		case '/':
		{
			if(ch == '+' || ch == '-') return '>';
			else if(ch == '*' || ch == '/') return '>';
			else if(ch == '(') return '<';
			else if(ch == ')') return '>';
			else return '>';
		}
			break;
		
		//括号在所有优先级以上 
		case '(':
		{
			if(ch == ')') return '=';
			else return '<';
		}
			break;
		case ')':
		{
			return '>';
		}
			break;
		case '\n':
		{
			if(ch == '\n') return '=';
			else return '<';
		}
			break;	
	}
}

/********************************************************************
描述:定义函数: Calculate,计算结果 
参数:int num1, char ch, int num2
返回值:返回两个数计算的结果result 
********************************************************************/
int Calculate(int num1, char ch, int num2)
{
	int result;
	switch(ch)
	{
		case '+':
			result = num1 + num2;
			break;
		case '-':
			result = num1 - num2; 
			break;
		case '*':
			result = num1 * num2;
			break;
		case '/':
			result = num1 / num2;
	}
	return result;
}

/********************************************************************
描述:定义函数:MainCalc,主要用于获取用户输入,并且进行计算 
参数:void 
返回值:result
********************************************************************/
int MainCalc()
{
	//主函数进行计算 
	OperateNum datas;
	OperateSymbol symbol;
	int num1, num2, result, num;
	char ch, sign;
	
	InitOperateNum(&datas);
	InitOperateSymbol(&symbol);
	
	
	//把回车计算的操作符放在栈中 
	PushOperateSymbol(&symbol, '\n');
	ch = getchar();
	while((ch != '\n') || (GetOperateSymbol(&symbol) != '\n'))
	{
		if(!IsOperateSymbolOrNum(ch))
		{
			num = atoi(&ch);  //将字符转换为整数
			ch = getchar();   //获取输入
			while(!IsOperateSymbolOrNum(ch))
			{
				num = num * 10 + atoi(&ch);
				ch = getchar();   //当没有输入回车时,继续获取输入
			} 
			PushOperateNum(&datas, num);			
		}
		else
		{
			switch(Priority(GetOperateSymbol(&symbol), ch))
			{
				//判断优先级后进行计算 
				case '<':
					PushOperateSymbol(&symbol, ch);
					ch = getchar();
					break;
				case '=':
					sign = PopOperateSymbol(&symbol);
					ch = getchar();  //获取输入
					break;
				case '>':
					sign = PopOperateSymbol(&symbol);
					num2 = PopOperateNum(&datas);
					num1 = PopOperateNum(&datas);
					result = Calculate(num1, sign, num2);
					PushOperateNum(&datas, result);
					break;
					 
			}
		} 
	} 
	result = GetOperateNum(&datas);
	return result;
}

int main(int argc, char *argv[])
{
	int result;
	result = MainCalc();
	printf("%d", result);  //输出结果 
	
	return 0;
}

 

 

欢迎关注我的个人Blog:[我的blog](https://www.finen.top)

 

### 关注我的微信公众账号,分享更多~
![微信公众账号](https://finen-1251602255.cos.ap-shanghai.myqcloud.com/weixin/qrcode.jpg)

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值