表达式求值【C语言实现】数据结构实验

本文介绍了一个C语言实现的算术表达式求值程序,使用栈来处理算符优先法,能够计算不含变量的整型四则混合运算表达式。程序包括运算符栈和操作数栈的初始化、入栈、出栈等操作,并通过示例展示了如何在求值过程中处理运算符和运算数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

表达式求值【C语言实现】数据结构实验
如果需要功能更完善、代码更简洁以及bug更少的代码,可以到我的小程序 航筱北同学上搜索查看。
在这里插入图片描述

实验内容

表达式计算是实现程序设计语言的基本问题之一,也是栈的应用的典型例子。设计一个程序,演示用算符优先法对算术表达式求值的过程。

实验要求

基本要求:以字符序列的形式从键盘输入语法正确的,不含变量的整型表达式。利用教科书表 3.1 给出的算符优先关系,实现对算术四则混合运算表达式的求值,并仿照教科书的例 3.1 演示在求值中运算符栈、运算数栈、输入字符和主要操作的变化过程。

实现提示

1 设置运算符栈和运算数栈辅助分析算符优先关系。
2 在读入表达式的字符序列的同时,完成运算符和运算数(整数)的识别处理,以及相应的运算。
3 在识别出运算数的同时,要将其字符序列形式转换成整数形式。
4 在程序的适当位置输出运算符栈、运算数栈、输入字符和主要操作的内容。
在这里插入图片描述

测试数据

在这里插入图片描述

C语言源代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define MAX_SIZE 1000

/*定义一个运算符栈*/
typedef struct {
	char Operator[MAX_SIZE];
	int top;
} OptorStack;
/*定义一个操作数栈*/
typedef struct {
	double Operand[MAX_SIZE];
	int top;
} OpndStack;
/*初始化运算符栈*/
void InitOptor(OptorStack *S) {
	S->top = -1;
}
/*初始化操作数栈*/
void InitOpnd(OpndStack *S) {
	S->top = -1;
}
/*运算符出栈*/
int PopOptor(OptorStack *S) {
	if(S->top==-1) {
		printf("运算符栈为空\n");
		exit(10);
	}
	S->top--;
	return 1;
}
/*操作数出栈*/
int PopOpnd(OpndStack *S) {
	if(S->top==-1) {
		printf("操作数栈为空\n");
		exit(11);
	}
	S->top--;
	return 1;
}

/*运算符入栈*/
int PushOptor(OptorStack *S,char ch) {
	if(S->top==MAX_SIZE-1) {
		printf("运算符栈满\n");
		exit(12);
	}
	S->top++;
	S->Operator[S->top]=ch;
	return 1;
}
/*操作数入栈*/
int PushOpnd(OpndStack *S,double ch) {
	if(S->top==MAX_SIZE-1) {
		printf("操作数栈满\n");
		exit(13);
	}
	S->top++;
	S->Operand[S->top]=ch;
	return 1;
}
/*取运算符栈栈顶元素*/
char GetOptor(OptorStack *S) {
	if(S->top==-1) {
		printf("运算符栈为空\n");
		exit(17);
	}
	return S->Operator[S->top];
}
/*取操作数栈栈顶元素*/
double GetOpnd(OpndStack *S) {
	if(S->top==-1) {
		printf("操作数栈为空\n");
		exit(18);
	}
	return S->Operand[S->top];
}
/*表达式运算函数*/
double Calculate(double a,double b,char op) {
	double result;
	if(op=='+') result=a+b;
	if(op=='-') result=a-b;
	if(op=='*') result=a*b;
	if(op=='/') {   //要防止除数为0
		if(b==0) {
			printf("ERROR:除数不能为0\n");
			exit(15);
		}
		result=a/b;
	}
	return result;    //返回结果result
}

int change(char ch) {
	switch(ch) {
		case '+':
			return 0;
		case '-':
			return 1;
		case '*':
			return 2;
		case '/':
			return 3;
		case '(':
			return 4;
		case ')':
			return 5;
		case '#':
			return 6;
	}
}
/*定义一个算符优先关系矩阵*/
char cmp[7][8]= {">><<<>>",">><<<>>",">>>><>>",">>>><>>","<<<<<=?",">>>>?>>","<<<<<?="};
/*算符比较函数,返回优先级:>或<或=*/
int Compare(char ch1,char ch2) {
	if(cmp[change(ch1)][change(ch2)]=='?') {
		printf("输入表达式错误");
		exit(16);
	}
	return cmp[change(ch1)][change(ch2)];
}
/*检查函数,用来检查输入的表达式的操作数和运算符的合法性*/
int Check(char *S,int len) {
	int i;
	for(i=0; i<len; i++) {
		if(S[i]>='0'&&S[i]<='9')continue;
		if(S[i]=='('||S[i]==')'||S[i]=='*'||S[i]=='/'||S[i]=='+'||S[i]=='-'||S[i]=='.')continue;
		return 0;
	}
	return 1;
}

int main() {
	char expre[9999],opd[9999];   //expre用来存储表达式,opd用来存操作数
	int len;
	OptorStack Optor;
	OpndStack Opnd;
	InitOptor(&Optor);
	InitOpnd(&Opnd);
	PushOptor(&Optor,'#');
	printf("请输入表达式:\n");
	scanf("%s",expre);
	len = strlen(expre);
	if (Check(expre,len) == 0) {
		printf("输入的表达式不合法,可能存在多余字符\n");
		exit(19);
	}
	int i,j=0,k=0;
	double x,y;
	expre[len] = '#';   //在expre数组后加个#结尾标志
	for (i=0; i<=len; i++) {
		if ((expre[i]>='0' && expre[i]<='9') || expre[i] == '.') {
			opd[k++] = expre[i];   //将数字字符存入操作数数组opd中
			j = 1;
			continue;
		}
		if(j) {
			opd[k] = '\0';
			PushOpnd(&Opnd,atof(opd));
			j=0;
			k=0;
		}
		switch (Compare(GetOptor(&Optor),expre[i])) {  //比较运算符栈的栈顶运算符和运算符expre[i]的优先级
			case '<':
				PushOptor(&Optor,expre[i]);
				break;
			case '=':
				PopOptor(&Optor);
				break;
			case '>':
				y = GetOpnd(&Opnd),PopOpnd(&Opnd);
				x = GetOpnd(&Opnd),PopOpnd(&Opnd);
				PushOpnd(&Opnd,Calculate(x,y,GetOptor(&Optor)));
				PopOptor(&Optor);
				i--;
				break;
		}
	}
	double final_result = GetOpnd(&Opnd);
	printf("该表达式的结果为:%.2lf",final_result);
	return 0;
}

运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值