C语言实现表达式分析并输出结果,注意:在处理小数的时候选择了向上向下取整,我暂时也没有能力解决。对了,代码也不是我的,也是曾经从CSDN上抄下来的,如有侵权,实在抱歉,第一次使用,请提醒我撤销,谢谢。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

#define STACK_INIT_SIZE 100
#define STACKINCREMENT 12
#define ERROR 0
#define OK 1
//运算数栈
typedef struct SqStack1
{

int *base; 
int *top;
int stacksize;

}SqStack1;
//运算符栈
typedef struct SqStack2
{

char *base;
char *top;
int stacksize;

}SqStack2;
//顺序栈的初始化

void IntInitStack(SqStack1 *S)
{

S->base=(int *)malloc(STACK_INIT_SIZE*sizeof(int));
if(!S->base) exit(ERROR);
S->top=S->base;
S->stacksize=STACK_INIT_SIZE;

}

void CharInitStack(SqStack2 *S)
{

S->base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));
if(!S->base) exit(ERROR);
S->top=S->base;
S->stacksize=STACK_INIT_SIZE;

}

int IntGetTop(SqStack1 *S) //取栈顶元素
{

int e;
if((*S).top==(*S).base)
return 0;
e=*((*S).top-1);
return e;

}

char CharGetTop(SqStack2 *S) //取栈顶元素
{

char e;
if((*S).top==(*S).base) return 0;
e=*((*S).top-1);
return e;

}

int IntPush(SqStack1 *S,int e)
{

*(*S).top++=e;
return OK;

}

int CharPush(SqStack2 *S,char e)
{

*(*S).top++=e;
return OK;

}

int IntPop(SqStack1 *S)
{

int e;
if((*S).top==(*S).base) return 0;
e=*--(*S).top;
return e;

}

int CharPop(SqStack2 *S)
{

char e;
if((*S).top==(*S).base) return 0;
e=*--(*S).top;
return e;

}

char Precede(char a,char b)//运算优先级判断
{

int i,j;
char Table[10][10]={
	' ','.','+','-','*','/','%','(',')','#',
	'.','>','>','>','>','>','>','>','>','>',
	'+','<','>','>','<','<','<','<','>','>',
	'-','<','>','>','<','<','<','<','>','>',
	'*','<','>','>','>','<','<','<','>','>',
	'/','<','>','>','>','<','<','<','>','>',
	'%','<','>','>','>','<','<','<','>','>',
	'(','<','<','<','<','<','<','<','=','>',
	')','<','>','>','>','<','<','=','>','>',
	'#','<','<','<','<','<','<','<','<','=',
}; //优先级表格
for(i=0;i<10;i++)
if(Table[0][i]==a) //纵坐标寻找
break;
for(j=0;j<10;j++) //横坐标寻找
if(Table[j][0]==b)
break;
return Table[j][i];

}

int Operate(int a,char theta,int b) //计算表达式值:主要是将大的表达式转化成小的表达式进行逐步求值
{

int c;
if(theta=='.')
{	float d;
	d=(float)b*0.1;
	//printf("%f",d);
	if(d<0.5)
	{
		c=floor(a+d);
	}
	else
	{
		c=ceil(a+d);
	}
	
} 
else if(theta=='+') c=a+b;
else if(theta=='-') c=a-b;
else if(theta=='*') c=a*b;
else if(theta=='/') c=a/b;
else c=a%b;
return c;

}//Operate

int In(char c) //判断c是否为操作符
{

if ( c=='.' ||c=='(' || c=='+' || c=='-' || c == '*' || c=='/' || c=='%' || c==')' || c=='#' || c=='^')
return 1;        //如果是操作符返回1
else
return 0;        //不是,返回0

}

int result(SqStack1 *OPND,SqStack2 *OPTR) //求值
{

char a=0;
char d=0;
char theta;
int b,c,number=0;
IntInitStack(OPND);
CharInitStack(OPTR);
CharPush(OPTR,'#');
a=getchar();

// printf("%c",a);

while(a!='#' || CharGetTop(OPTR)!='#')
{	
	if(In(a))
	{
		printf("输入字符:%c    ",a);
	}
	
	if(!In(a))    //不是运算符则进栈
	{
	//	printf("输入字符:%c    ",a);
		number=0;
		while(!In(a))   
		{
			
			number = number*10 +(a-48);        //处理多位整数 z=10*x+y
			printf("输入字符:%c    ",a);
			a = getchar();
		}
	//	printf("输入字符:%c    ",a);
		IntPush(OPND,number);
		printf("主要操作:Push(OPND,%d)      ",number);
	}
else
	switch(Precede(a,CharGetTop(OPTR)))
	{
		case '<':
		CharPush(OPTR,a);
		a=getchar();
		printf("主要操作:Push(OPTR,%c)      ",a);
		break;
		case '=':
		CharPop(OPTR);
		a=getchar();
		printf("主要操作:Pop(OPTR,%c)        ",a);
		break;
		case '>':
		theta=CharPop(OPTR);
		c=IntPop(OPND);
		b=IntPop(OPND);
		IntPush(OPND,Operate(b,theta,c));
		printf("主要操作:Operate(%d,%c,%d)    ",b,theta,c);
		break;
	}
	printf("OPND栈:%d  OPTR栈:%c\n",IntGetTop(OPND),CharGetTop(OPTR));
}
printf("\n结果:%d.\n",IntGetTop(OPND)); //打印输出表达式值
return OK;

}

void result1()
{

SqStack1 s1,*OPND;
SqStack2 s2,*OPTR;
OPND=&s1;
OPTR=&s2; 
printf("请输入算数表达式并以'#'结尾.\n");
//printf("表达式不支持浮点数.\n");
printf("算数表达式:");
result(OPND,OPTR);

}

void showMenu()
{

printf("********表达式求值**********");
printf("\n\n");
printf("\t 1.输入表达式\n");
printf("\t 2.清屏\n");
printf("\t 3.退出\n"); 

}

void main()//主函数,使用自定义函数完成功能
{

int select;
while(1)
{
	showMenu();
	printf("请选择需要的操作:");
	scanf("%d",&select);
	fflush(stdin);
	switch(select)
	{
	 case 1:result1();break;
	 case 2:system("cls");break;
	 case 3:exit(0);
	 default:printf("\n**********请重新输入正确的选项:*******\n\n"); 
	} 
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值