称不上项目的小程序3:计算器

这是用2个栈实现一个小计算器功能,包含的运算符有:+ , - ,  * ,  / ,  ( , ) ,可谓“功能强大”!

(这次可是很用心的加了很多注释的,好吧,是我之前的程序都没用心加)


1、calculatestack.h

#ifndef __CALCULATESTACK_H__
#define __CALCULATESTACK_H__

#define TRUE  1
#define FALSE 0
#define PUSH 1
#define JISUAN 0

#define SIZE 50

typedef struct _num
{
	int num[SIZE];    // 栈数组
	int top;          // 栈顶元素下标
}Num;

typedef struct _opt
{
	char opt[SIZE];    
	int top;         
}Opt;
	
// 置空栈
int InitStack_Opt (Opt *S); 		
int InitStack_Num (Num *S); 

// 判断输入类型,数字返T,字符返F
int judge_type (char ch);

// 进栈
int Push_NUM (Num *s, int x);
int Push_Opt (Opt *s, char ch);	

// 出栈
int Pop_Num (Num *s, int *x); 	
int Pop_Opt (Opt *s, char *ch);

// 判断运算符是否进行计算
int judge_op (Opt *s, char ch);

// 计算
int Jisuan (Num *s_num, Opt *s_opt);

#endif // __CALCULATESTACK_H__

2、calculatestack.c

#include "calculateStack.h"

// 置空栈
int InitStack_Num (Num *S)	
{
	if (S == NULL)
	{
		errno = ERROR;
		return FALSE;
	}
	S->top = -1;
	return TRUE;
}
int InitStack_Opt (Opt *S)	
{
	if (S == NULL)
	{
		errno = ERROR;
		return FALSE;
	}
	S->top = -1;
	return TRUE;
}

// 判断输入类型
int judge_type (char ch)
{
	if (ch >= '0' && ch <= '9')
		return TRUE;   // 数字返TRUE
	else
		return FALSE;  // 字符返FALSE
}

// 进栈
int Push_Num (Num *s, int x)
{
	// 判断是否满栈
	if (s->top == SIZE -1)
	{
		errno = FULL_STACK;
		return FALSE;
	}
	else
	{
		s->num[++s->top] = x;
		return TRUE;
	}
}
int Push_Opt (Opt *s, char ch)
{
	// 判断是否满栈
	if (s->top == SIZE -1)
	{
		errno = FULL_STACK;
		return FALSE;
	}
	else
	{
		s->opt[++s->top] = ch;
		return TRUE;
	}
}

// 出栈
int Pop_Num (Num *s, int *x)
{
	// 判断是否空栈
	if (s->top == -1)
	{
		errno = EMPTY_STACK;
		return FALSE;
	}

	*x = s->num[s->top--];  // x用来保存出栈的数字
	return TRUE;
}
int Pop_Opt (Opt *s, char *ch)
{
	// 判断是否空栈
	if (s->top == -1)
	{
		errno = EMPTY_STACK;
		return FALSE;
	}

	*ch = s->opt[s->top--];  // ch用来保存出栈的字符
	return TRUE;
}

// 先计算再入栈
int Jisuan (Num *s_num, Opt *s_opt)
{
	// 判断数字栈中是否还有2个数据
	if (s_num->top == 0)
	{
		errno = ERROR;
		myError("s_num->top == 0");
		return FALSE;
	}
	// 判断字符栈中是否还有1个数据
	if (s_opt->top == -1)
	{
		errno = EMPTY_STACK;
		myError("s_opt->top == -1");
		return FALSE;
	}
	int num1, num2, num3;
	Pop_Num (s_num, &num1);
	Pop_Num (s_num, &num2);  // 取出数据
	char ch;
	Pop_Opt (s_opt, &ch);    // 取出字符
	if (ch == '+') 
		num3 = num2 + num1;
	else if (ch == '-')
		num3 = num2 - num1;
	else if (ch == '*')
		num3 = num2 * num1;
	else if (ch == '/')
	{
		if (num1 == 0)
		{
			printf ("分母为0,错误\n");
			return FALSE;
		}
		else
			num3 = num2 / num1;
	}
	Push_Num (s_num, num3);  // 将计算结果入数字栈
	return TRUE;
}	


// 判断运算符是否进行计算
int judge_op (Opt *s, char ch)
{
	// 栈空或传入的字符为'('则直接进栈
	if (s->top == -1 || ch == '(')  
	{
		return PUSH;
	}
	else
	{	
		switch (s->opt[s->top])
		{
			case '+':
			case '-':
				if (ch == '+' || ch == '-')  // 栈顶为'+','-'时
					return JISUAN;			 // 加减需计算
				else
					return PUSH;             // 其他全进栈
				break;
			case '*':
			case '/':
				return JISUAN;				 // 栈顶为'*','/'时全部进计算
				break;
			case '(':
				return PUSH;				 // 栈顶为'(' 全部进栈
				break;
		}
	}
}
			
3、main.c
#include <stdio.h>
#include <stdlib.h>
#include "calculateStack.h"

int main()
{
	Num s_num;
	Opt s_opt;
	if (InitStack_Num(&s_num) == FALSE)
	{
		printf ("errno:%d\n", errno);
		char * a = myStrError(errno);		
		printf ("a: %s\n", a);
	}
	if (InitStack_Opt(&s_opt) == FALSE)
	{
		printf ("errno:%d\n", errno);
		char * a = myStrError(errno);
		printf ("a: %s\n", a);
	}
	
	char a[SIZE];     // 临时存放用来转化为数字的字符串
	char str[SIZE];
	printf ("请输入算式:");
	scanf ("%s",str);
	getchar();
	
	int i = 0;
	while (str[i] != '\0')
	{	
		// 	判断输入的是否为数字
		if (judge_type (str[i]) == TRUE)
		{
			int j = 0;			
			while (judge_type (str[i]) == TRUE)    // 判断接下来的字符是否为数字
			{
				a[j++] = str[i];                 
				i++;
			}
			a[j] = '\0';
			i--;
			Push_Num (&s_num, atoi(a));            // 数字进栈
		}
		else 
		{
			if (str[i] == ')')         // 如果进来的字符是')'则计算至'('
			{
				while (s_opt.opt[s_opt.top] != '(')
				{
					Jisuan(&s_num, &s_opt);
				}
				char ch1[SIZE] = {0};
				Pop_Opt (&s_opt, ch1);   // 左括号出栈
			}
			//  判断进栈还是计算
			else if (judge_op (&s_opt, str[i]) == PUSH)	 		
			{
				Push_Opt (&s_opt, str[i]);
			}
			else	
			{	
				Jisuan (&s_num, &s_opt);    // 计算上一个字符
				Push_Opt (&s_opt, str[i]);  // 此字符进栈
			}
		}
		i++;
	}
	while (s_opt.top != -1)       // 将栈中存放的字符全部计算掉
	{
		Jisuan (&s_num, &s_opt);
	}
	if (s_num.top != 0)           // 若数字栈中不是存放了一个结果则输入有误
	{
		printf ("输入格式错误!\n");
	}
	else
	{
		printf ("答案是:%d\n",s_num.num[s_num.top]);
	}
	
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值