计算器

#ifndef _CALCULATOR_H__
#define _CALCULATOR_H__
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

#define MAX 100
typedef char ElemType;
#define STACK_INIT_MEMORY 100
#define STACK_GROW_MEMORY 10

typedef struct stack
{
	ElemType *esp;
	ElemType *ebp;
	int size;                           //记录当前栈内空间最多能存几个元素
}Stack,*pStack;

typedef struct stack_num
{
	int *esp;
	int *ebp;
	int size;                           //记录当前栈内空间最多能存几个元素
}Stack_num, *pStack_num;

void CreateExpression(ElemType *arr);
void TransmitExpression(ElemType *arr);
int EvaluateExpression();
void CreateStack(pStack S);
void push(pStack S, ElemType x);
int pop(pStack S, ElemType *x);
void valuation();
int judge_type(char c);
char judge_priority(pStack S, char c);
int operation(int a, ElemType symbol, int b);

void CreateStack_num(pStack_num S);
void push_num(pStack_num S,int x);
int pop_num(pStack_num S, int *x);


#endif 




#include"calculator.h"

char dst[] = { '+', '-', '*', '/', '(', ')' };
char list[6][6] = { 0 };
ElemType post[MAX] = {0};

void valuation()
{
	int arr1[6] = {1,1,2,2,3,0};                         
	int i = 0;
	int j = 0;
	for (int i = 0; i < 6; i++)
	{
		for (int j = 0; j < 6; j++)
		{
			if (i == 4)                                  //如果栈顶符号是‘(’,则它的优先级最小
			{
				if (j==5)                                 //'(',')'的优先级相同
				list[i][j] = '=';
				else
					list[i][j] = '<';
			}
			else
			{
				if (arr1[i] >= arr1[j])
					list[i][j] = '>';                        //栈顶优先级高
				else if (arr1[i] <= arr1[j])
					list[i][j] = '<';                        //读取的运算符优先级高
			}

		}
	}
}

int judge_type(char c)                             //判断读取的是数字还是字符
{
	int i = 0;
	for (i = 0; i < 6; i++)
	{
		if (dst[i] == c)
			return 0;                        //如果是数符号则返回0
	}
	if (c == ' ')
		return -1;                           //如果是空格则返回-1
	return 1;                                 //如果是数字则返回1
		                                 
}

char judge_priority(pStack S,char c)                  //判断栈顶运算符与读取的运算符的优先级
{                               
	int line = 0;
	int row = 0;
	for (line = 0; line < 6; line++)
	{
		if (dst[line] == *(S->esp - 1))         //将栈顶符号在dst[]中的位置作为行下标
			break;
	}
	for (row = 0; row < 6; row++)
	{
		if (dst[row] == c)                     //将读取的运算符在dst[]中的位置作为列下标
			break;
	}
	return list[line][row];                      //通过优先级表,返回优先级关系
}





int operation(int a,ElemType symbol, int b)
{
	int ret = 0;
	switch (symbol)
	{
		case '+':
			ret = a + b;
			break;
	   case '-':
		   ret = a - b;
		   break;
	    case '*':
			ret = a*b;
			break;
	    case '/':
			if (b == 0)
			{
				perror("除数不能为零。/n");
				exit(1);
			}
		ret = a / b;
		break;
	}
	return ret;
}



void CreateExpression(ElemType *arr)
{
	scanf("%s", arr);
}


void TransmitExpression(ElemType *arr)
{
	valuation();
	assert(arr);
	Stack S;
	CreateStack(&S);                                 //创建一个栈
	ElemType x= 0;
	int i = 0;
	int j = 0;
	while (arr[i] != '\0')
	{ 
		if (judge_type(arr[i]) == 1)                          //判断是不是数字
		{
			post[j++] = arr[i];                               //数字则直接存入post[]
			if (judge_type(arr[i+1]) != 1)
				post[j++]=' ';                                //以空格隔开
			i++;
		}
		else
		{
			if (S.ebp == S.esp)                            //如果栈为空,压栈
			{
				push(&S, arr[i]);
				i++;
			}
			else
			{
				switch (judge_priority(&S, arr[i]))
				{
				case '<':                              //如果栈顶的优先级低。则直接入栈
					push(&S, arr[i]);
					i++;
					break;
				case '>':                             //如果读取的优先级高,则栈顶先退栈
					pop(&S, &x);
					post[j++] = x;
					post[j++] = ' ';
					break;
				case '=':
					pop(&S, &x);
					i++;
					break;
				}
			}
		}
	}
	while (pop(&S, &x))
	{
		if (x != '('&&x != ')')
		{
			post[j++] = x;
			post[j++] = ' ';
		}
	}
	printf("%s\n", post);
	free(S.ebp);
}


int EvaluateExpression()
{
	int i = 0;
	Stack_num S;
	int ret = 0;
	int a = 0;
	int b = 0;
	CreateStack_num(&S);
	while (post[i] != '\0')
	{
		switch (judge_type(post[i]))               
		{
		case 0:                                     //读取的是符号
			pop_num(&S, &b);                        //取除数字栈的栈顶元素
			pop_num(&S,&a);                         //取除数字栈的栈顶元素
			ret=operation(a,post[i],b);           //对这两个数进行运算
			push_num(&S, ret);                      //将运算结果入站
			i++;
			ret = 0;
			break;
		case 1:       
			while(judge_type(post[i])==1)
			{
				ret = ret * 10 + post[i] - '0';        //将字符数字转换成对应的整数
				i++;
			}
			push_num(&S, ret);                        //将这个数字进行压栈
			ret = 0;
			break;
		case -1:                                    //读取的是空格
			i++;
			break;
		}
	}
	ret = *(--(S.esp));                            //弹出栈底数字
	free(S.ebp);
	return ret;
}



void CreateStack(pStack S)
{
	S->ebp = (ElemType *)malloc(sizeof(ElemType)* STACK_INIT_MEMORY);
	if (S->ebp == NULL)                      //判断动态内存是否开辟成功
		exit(1);
	S->size = STACK_INIT_MEMORY;
	S->esp = S->ebp;
}


void push(pStack S, ElemType x)
{
	if (S->esp - S->ebp >= S->size)         //判断当前栈是否已满
	{                                       //栈满追加空间
		S->ebp = (ElemType *)realloc(S->ebp, sizeof(ElemType)*(S->size + STACK_GROW_MEMORY));
		if (S->ebp == NULL)                 //判断内存是否开辟成功
			exit(1);
		S->esp = S->ebp + S->size;              //让栈顶指针向后偏移指向要入栈的位置
		S->size += STACK_GROW_MEMORY;
	}
	*(S->esp)++ = x;
}


int pop(pStack S,ElemType *x)
{
	if (S->esp == S->ebp)
	{
		return 0;     //栈已空
	}
	else
	{
		S->esp--;
		*x = *(S->esp);
		return 1;     //退栈成功
	}
}




void CreateStack_num(pStack_num S)
{
	S->ebp = (int *)malloc(sizeof(int)* STACK_INIT_MEMORY);
	if (S->ebp == NULL)                      //判断动态内存是否开辟成功
		exit(1);
	S->size = STACK_INIT_MEMORY;
	S->esp = S->ebp;
}


void push_num(pStack_num S, int x)
{
	if (S->esp - S->ebp >= S->size)         //判断当前栈是否已满
	{                                       //栈满追加空间
		S->ebp = (int *)realloc(S->ebp, sizeof(int)*(S->size + STACK_GROW_MEMORY));
		if (S->ebp == NULL)                 //判断内存是否开辟成功
			exit(1);
		S->esp = S->ebp + S->size;              //让栈顶指针向后偏移指向要入栈的位置
		S->size += STACK_GROW_MEMORY;
	}
	*(S->esp)++ = x;
}


int pop_num(pStack_num S,int *x)
{
	if (S->esp == S->ebp)
	{
		return 0;     //栈已空
	}
	else
	{
		*x = *(--S->esp);
		return 1;     //退栈成功
	}
}




#include"calculator.h"


void Menu()
{
	printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    printf("*0.exit                 1.Create_Expr   *\n");
	printf("*2.Transmit_Expr        3.Evaluate_Expr *\n\n");
	printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n");
	printf("请选择:>");
}

void test()
{
	ElemType arr[MAX] = { 0 };
	int n = 0;
	int ret = 0;
	ElemType *p = NULL;
	while (1)
	{
		Menu();
		scanf("%d", &n);
		switch (n)
		{
		case 0:
			exit(1);
			break;
		case 1:
			printf("请输入一个合法的中缀表达式\n");
			CreateExpression(arr);
			printf("%s\n", arr);
			break;
		case 2:
			TransmitExpression(arr);

			break;
		case 3:
			ret=EvaluateExpression();
			printf("%d\n",ret);
			break;
		default:
			printf("选择无效\n");
			break;
		}

	}
}



int main()
{
	test();
	system("pause");
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自1.6版以后,增加了表达式计算的功能,从此可以进行复杂的公式计算,如输入以下公式“2+(18-10)/7^2+sin(1)+sqrt(sqrt(5),3)*2”,按下计算按钮或回车会自动得出最终结果。另外增加了一个“单步求解”的选项,可以一步一步显示出公式的计算过程。支持各种三角函数,运算的结果可选择弧度或角度值,这取决于计算器的角度|弧度按钮选择。打开表达式计算的功能步骤是:鼠标右键单击液晶屏幕,在弹出的菜单中选择“* 表达式(公式)计算 *”一项,即可打开该功能。(注:表达式功能不能在小窗口状态下使用),另外,v1.6版还改进了许多以前版本中不方便或有BUG的地方,使用更加方便!增加了十几种三角函数运算(包括各种双曲正弦、余弦、正割、余割等等以及相关反函数),加入了角度与弧度计算,加入了位移指令,增加了各种常用常数表,使用户在计算一些常用公式时,不必再去翻书查找。加入了各种单位换算,单位换算与屏幕计算结果实时换算,并可实时改变换算单位。并修改了数据转换为"人民币中文大写形式、人民币数字形式(例如:1435.75、人民币壹仟肆佰叁拾伍圆柒角伍分、¥1435.75)的一些BUG,大大方便了财务、票据等方面的工作,输入的任何数据和计算结果可自动输入在其它程序窗口当前光标位置,就像和其它程序融为一体一样。如果用户经常在应用软件中做计算输入工作(例如各种文字处理、制表、工程计算、股票等等一切需要输入计算数据和结果的地方。),那么这个功能将使工作变得非常方便!(如果不需要这项功能,鼠标右键单击液晶屏幕,在弹出的菜单中取消“数据自动输入其它窗口”一项即可!)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值