C语言中缀表达式的计算

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100  
typedef float Num;//为防止以后变换操作数类型需要 
typedef struct
{
	Num data[MAX];
	int top;
}StackNum;//运算数栈 
typedef struct
{
	char data[MAX];
	int top;
}StackChar;//运算符栈 
//------函数声明---------
void InitNum(StackNum *p);//运算数栈初始化 
void PushNum(StackNum *p, Num e);//运算数压栈 
void PopNum(StackNum *p, Num *e);//运算数出栈
Num GetNum(StackNum p);//取栈顶元素 
//-----------------------
void InitChar(StackChar *p);//运算符栈初始化
void PushChar(StackChar *p, char e);//运算符压栈 
void PopChar(StackChar *p, char *e);//运算符出栈 
//-----------------------
void Fun(StackNum *p, char e);//计算并压入运算数栈 
//-----------------------
int main()
{
	int i;//循环变量 
	Num temp;//存放一个临时转换数
	char str[MAX], ch;//存放中缀表达式原式,临时运算符 
	//-----------
	StackNum n1;
	StackChar c1;
	InitNum(&n1);
	InitChar(&c1);
	//------------
	for (;;)
	{
		printf("请输入中缀表达式:");
		gets(str);
		/*
		注意字符串输入函数与scanf("%s",str) 的区别,scanf遇到空白字符,
		包括空格,制表符,换行符时均会停止输入,所以不可取,而gets功能为读入一行,
		并将换行符转换为字符串结束符。
		*/
		for (i = 0; str[i] != '\0'; i++)//读完整字符串-----字符串结束标志'\0' 
		{
			if (str[i] >= '0'&&str[i] <= '9')//分岔点一:----------------------------------------------------------------如果为数字 
			{
				temp = str[i] - '0';//-----将字符转换为数值 


				while (str[i + 1] != '\0')//多位数值获取 
				{
					if (str[i + 1] >= '0'&&str[i + 1] <= '9')
					{
						temp = temp * 10 + str[i + 1] - '0';//------注意! 

						i++;
					}
					else
						break;//如果不是多位数字,则跳出多位获取循环 
				}
				PushNum(&n1, temp);//将获取来的数值入栈 
			}
			else if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' || str[i] == '(' || str[i] == ')')//分岔点二:-------如果为运算符 
			{
				switch (str[i])//表达式可为:整型/字符型/枚举型-----C语言中 
				{
					//case 后可为 整型,字符型----C语言中 
				case '+':
					if (c1.data[c1.top - 1] != '+'&&c1.data[c1.top - 1] != '-'&&c1.data[c1.top - 1] != '*'&&c1.data[c1.top - 1] != '/')
					{
						PushChar(&c1, '+');
					}
					else//如果不然,则将之前的先都出栈并计算,然后再入栈
					{
						while (c1.top > 0 && c1.data[c1.top - 1] != '(')//将优先级高的运算符先输出计算,其中括号内的优先级最高 
						{
							PopChar(&c1, &ch);
							Fun(&n1, ch);//计算,并压运算数栈

						}
						PushChar(&c1,'+');
					}
					; break;
				case '-':
					if (c1.data[c1.top - 1] != '+'&&c1.data[c1.top - 1] != '-'&&c1.data[c1.top - 1] != '*'&&c1.data[c1.top - 1] != '/')
					{
						PushChar(&c1, '-');
					}
					else//如果不然,则将之前的先都出栈并计算,然后再入栈
					{
						while (c1.top > 0 && c1.data[c1.top - 1] != '(')//将优先级高的运算符先输出计算,其中括号内的优先级最高 
						{
							PopChar(&c1, &ch);
							Fun(&n1, ch);//计算,并压运算数栈

						}
						PushChar(&c1, '-');
					}
					; break;
				case '*':
					if (c1.data[c1.top - 1] != '*'&&c1.data[c1.top - 1] != '/')
					{
						PushChar(&c1, '*');
					}
					else//如果不然,则将之前的先都出栈并计算,然后再入栈
					{
						while (c1.top > 0 && c1.data[c1.top - 1] != '(')//将优先级高的运算符先输出计算,其中括号内的优先级最高 
						{
							PopChar(&c1, &ch);
							Fun(&n1, ch);//计算,并压运算数栈

						}
						PushChar(&c1, '*');
					}
					; break;
				case '/':
					if (c1.data[c1.top - 1] != '*'&&c1.data[c1.top - 1] != '/')
					{
						PushChar(&c1, '/');
					}
					else//如果不然,则将之前的先都出栈并计算,然后再入栈
					{
						while (c1.top > 0 && c1.data[c1.top - 1] != '(')//将优先级高的运算符先输出计算,其中括号内的优先级最高 
						{
							PopChar(&c1, &ch);
							Fun(&n1, ch);//计算,并压运算数栈

						}
						PushChar(&c1, '/');
					}
					; break;
				case '(':

					PushChar(&c1, '(');

					; break;
				case ')'://并没有将'('压入栈中,只是当作一种出栈信号 
					while (c1.data[c1.top - 1] != '(')
					{
						PopChar(&c1, &ch);
						Fun(&n1, ch);//计算,并压运算数栈
					}
					PopChar(&c1, &ch);//将'('也出栈,但并不计算 
					; break;
				}

			}
		}
		while (c1.top > 0)//将剩余的运算符出栈并计算 
		{
			PopChar(&c1, &ch);
			Fun(&n1, ch);
		}
		printf("\t\t%s=%.2f", str, GetNum(n1));
		printf("\n");
		system("pause");
	}
	
}
void InitNum(StackNum *p)
{
	p->top = 0;
}
void InitChar(StackChar *p)
{
	p->top = 0;
}
void PushNum(StackNum *p, Num e)
{
	if (p->top == MAX)
		printf("运算数栈满!\n");
	else
	{
		p->data[p->top] = e;
		p->top++;
	}
}
void PushChar(StackChar *p, char e)
{
	if (p->top == MAX)
		printf("运算符栈满!\n");
	else
	{
		p->data[p->top] = e;
		p->top++;
	}
}
void PopNum(StackNum *p, Num *e)
{
	if (p->top == 0)
		printf("运算数栈空!\n");
	else
	{
		p->top--;
		*e = p->data[p->top];
	}
}
void PopChar(StackChar *p, char *e)
{
	if (p->top == 0)
		printf("运算符栈空!\n");
	else
	{
		p->top--;
		*e = p->data[p->top];
	}
}
void Fun(StackNum *p, char e)
{
	Num temp1, temp2;//存放两个临时操作数 
	PopNum(p, &temp2);
	PopNum(p, &temp1);
	switch (e)
	{
	case '+':PushNum(p, temp1 + temp2); break;
	case '-':PushNum(p, temp1 - temp2); break;
	case '*':PushNum(p, temp1*temp2); break;
	case '/':PushNum(p, temp1 / temp2); break;

	}
}
Num GetNum(StackNum p)
{
	return p.data[p.top - 1];
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值