用栈实现简易计算器功能

这是一个使用C语言编写的简单计算器程序,通过栈来处理运算符的优先级问题。程序首先判断输入字符是否为数字或运算符,然后根据运算符的优先级决定是否入栈或进行计算。最终实现了加、减、乘、除的功能。

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

#include <stdio.h>
#include "SqStack.h"


//判断是否是数字
int is_digital_str(char ch)
{
	if(ch >= '0' && ch <= '9')
	{
		return 1;
	}
	return 0;
}

//判断是否为符号
int is_operand_str(char ch)
{
	if(ch == '*' || ch == '+' || ch == '-' || ch == '%' || ch == '/')
	{
		return 1;
	}
	return 0;
}
//判断是否进栈			优先级			ch1是待进栈元素			ch2是栈顶元素
int is_compare_operand(char ch1,char ch2)		//大可以从反面来看,以少胜多,只有一种情况栈顶元素不出栈
{
	if( (ch1 == '*' || ch1 == '%' || ch1 == '/') && (ch2 == '+' || ch2 == '-'))
	{
		return 1;
	}
	return 0;
}

//计算吧肿瘤君
int calculate(struct SqStack*sq,struct SqStack*so)
{
	//数字出栈
	int a,b;
	pop(sq,&b);
	pop(sq,&a);
	//符号出栈
	int c;
	pop(so,&c);

	switch (c)					//switch 语句来解决冗杂的问题
	{
		case '*': return a*b;
		case '%': return a%b;
		case '/': return a/b;
		case '+': return a+b;
		case '-': return a-b;
		default:
				return 0;
	}
}
//计算器
int expression(char *str)
{
	//如果表达式为空则返回零
	if(str == NULL)
	{
		printf("你只是没输入数字");
		return 0;
	}
	//初始化栈
	struct SqStack * sq = InitStack();			//数字栈
	struct SqStack * so = InitStack();			//符号栈
	
	while(*str)								//首地址的指针传进来
	{
		int sum = 0;				//用来存高位数
		while(is_digital_str(*str))			//因为要对他进行操作,所以传进来
		{
			sum = sum*10 + (*str-'0');
			str++;
		}
		push(sq,sum);
		
		if(*str == '\0')			//字符串结束
		{
			break;
		}
		if(is_operand_str(*str))		//如果是操作符就进来
		{
			while(1)
			{
				int top;
				GetTop(so,&top);			//具现化栈顶元素

				//栈里没有符号或者栈里优先级低就入栈
				if(IsEmpty(so) || is_compare_operand(*str,top))		
				{
					push(so,*str);
					break;
				}
				else								//不进栈我就出栈,逆水行舟,不进则退
				{
					int gap = calculate(sq,so);			//出栈计算函数
					
					//把结果入栈
					push(sq,gap);
				}
			}
		}
		str++;
	}
	while( ! IsEmpty(so) )			//符号栈不为空
	{
		//如果最后符号栈还有元素就全部拿出来计算
		push(sq,calculate(sq,so));
	}
	int ret;			//拿出最后的结果
	pop(sq,&ret);

	Destroy_Stack(sq);
	Destroy_Stack(so);
	
	return ret;
}

int main()
{
	char str[100] = {0};
	scanf("%s",str);
	
	int k = expression(str);
	printf("%d",k);
	
	return 0;
}

























栈相关的代码

#include "SqStack.h"
#include <stdio.h>
#include <stdlib.h>

	//对栈初始化
	struct SqStack * InitStack()
	{
		struct SqStack * s = malloc(sizeof(struct SqStack));
	
		s->data = malloc(sizeof(ElemType) * MAX_LEN);
	
		s->top = -1;
	
		return s;
	}
	
	//摧毁栈
	void Destroy_Stack(struct SqStack*s)
	{
		if(s == NULL)		//销毁成功
		{
			return ;
		}
		if(s->data) 		//栈里有数据
		{
			s->top = -1;		/*清空之后只能入栈,从-1开始,会把原来的数据覆盖,相应的在出栈的时候
								是从新的top开始,只有被更新的数据才会出来*/
			free(s->data);		//释放空间
		}
	}
	
	//清空栈
	void ClearStack(struct SqStack * s)
	{
		if(s)		//栈存在
		{
			s->top = -1;			//只需要把下表置为-1,他下一个元素入栈时会自动更新,不需要再主动删除
		}
	}
	
	//判断栈是否为空
	int IsEmpty(struct SqStack *s)
	{
		if(s == NULL || s->top == -1)
		{
			return 1;
		}
		return 0;
	}
	
	
	//求栈长度
	int StackLength(struct SqStack *s)
	{
		if(s == NULL)
		{
			return 0;
		}
		return s->top+1;
	}
	
	
	//出栈
	int  pop(struct SqStack *s,ElemType *x) 
	{
		//栈为空(s不存在或者s->data这个数组不存在,里面没有东西)
		if(s == NULL || s->data == NULL || s->top == -1)		
		{
			printf("出栈失败");
			return 0;
		}
		else
		{
			*x = s->data[(s->top)--];		/*获取栈顶元素,为什么要传地址?如果传进来的是一个值
											因为形参和实参的作用域,他不会把值传出去,所以要传地址进来
											让他们指向同一个地址,值才会同时改变*/
			return 1;
		}
	}
	
	/*
		出栈 
			返回值:
				1	出栈成功
				0	出栈失败
	*/
	int push(struct SqStack *s,ElemType x)/*进栈时不需要传地址,是因为它只需要对栈进行操作,形参的变化不关心*/
	{
		//当栈为空(s不存在,s->data这个数组不存在),栈满了时不可入栈
		if(s == NULL || s->data == NULL || s->top == MAX_LEN-1) 		//栈从零开始计数
		{
			printf("入栈失败");
			return 0;
		}
		s->data[++(s->top)] = x;
		return 1;
	}
	
	//获取栈顶元素,但不销毁他
	int GetTop(struct SqStack *s,ElemType *x)
	{
		//栈为空,没有数据
		if(s == NULL || s->data == NULL || s->top == -1)
		{
			printf("里面没有数");
			return 0;

	}
	*x = s->data[(s->top)];
	return 1;
}

自定义头文件

#ifndef __SQSTACK_H__
#define __SQSTACK_H__

#define MAX_LEN 10

typedef int ElemType;

typedef struct SqStack
{
	ElemType * data;//data指向一块地址连续的空间,来存储栈的每一个元素
								// data = malloc( sizeof(ElemType) * MAX_LEN );
								// ElemType data[MAX_LEN];
	int top;			//栈顶,指定栈顶元素的下标
						// top == -1   表示栈中没有元素,空栈
}SQSTACK;

struct SqStack * InitStack();

int push(struct SqStack *s,ElemType x);

int pop(struct SqStack *s,ElemType *x);

int StackLength(struct SqStack *s);

void Destroy_Stack(struct SqStack*s);

void ClearStack(struct SqStack * s);

int GetTop(struct SqStack *s,ElemType *x);

int IsEmpty(struct SqStack *s);



#endif

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值