C语言实现计算器+-*/连加运算

1 篇文章 0 订阅

对于栈的概念这里不做再多说明,先进后出,后进先出。这里用到两个栈,计算栈和操作栈

输入一个算数表达式(中序表达式)之后,从头遍历,如果是数字的话直接放到一个计算栈中准备计算,如果是符号的话按照符号的权值对符合进行进出操作栈操作

代码如下(运行环境VS2015版本)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define STRING_MAX_LENGTH 10
#define STACK_MAX_LENGTH 20
#pragma warning(disable:4996)
#define BIG 1
#define SMALL_OR_EQUAL 0
#define EMPTY  1
#define IS_NUM 1
#define IS_CHAR 0
#define EXP_lENGTH 100
#define TABLE {'#', 0, 0}, { '(',1,8 }, { '^',7,6 }, { '*',5,4 }, { '/',5,4 }, { '+',3,2 }, { '-',3,2 }, { ')',8,1 }
//操作符
struct Operator{
	char operator;																	//操作符
	int isp;																		//栈顶权值
	int icp;																		//栈外权值
};
//栈 
struct Stack{
	char item[STACK_MAX_LENGTH][STRING_MAX_LENGTH];									//栈内的每一项元素
	int length;																		//栈的长度
	int topPoint;																	//栈的顶元素标号
};
//实例化一个栈
void inntStack(struct Stack *stack){
	stack->length = 0;
	stack->topPoint = -1;
}
//进栈
int pushItme(struct Stack *stack,char *item) {
	stack->topPoint++;
	strcpy(stack->item[stack->topPoint], item);
	stack->length++;
	return 0;
}
//出栈
int popItem(struct Stack *stack) {
	stack->topPoint--;
	stack->length--;
	return 0;
}
//取栈顶元素
char * topItem(struct Stack *stack){
	return stack->item[stack->topPoint];
}
//打印输出栈内所有元素
void printStack(struct Stack *stack) {
	int i;
	for (i = 0; i < stack->length; i++) {
		printf("%s\n",stack->item[i]);
	}
}
//判断是字符还是数字
int isCharOrNum(char ch) {
	if (ch >= '0' && ch <= '9') {
		return IS_NUM;
	}
	else
		return IS_CHAR;
}
//比较栈内栈外两个操作符的权值大小 ch1为栈内的 ch2为栈外的
int compareOperator(char ch1,char ch2) {
	int i;
	int j;
	struct Operator operator_table[8] = { TABLE };
	for ( i = 0; i < 8; i++){
		if (ch1==operator_table[i].operator){
			break;
		}
	}
	for ( j = 0; j < 8; j++){
		if (ch2==operator_table[j].operator){
			break;
		}
	}
	if (operator_table[i].isp>operator_table[j].icp){
		return BIG;
	}
	//栈内小于等于栈外
	if (operator_table[i].isp < operator_table[j].icp|| operator_table[i].isp == operator_table[j].icp) {
		return SMALL_OR_EQUAL;
	}
}
//判断一个栈是否为空
int isEmpty(struct Stack *stack) {
	if (stack->length ==0 ) {
		return EMPTY;
	}
	else {
		return 0;
	}
}
int getTowItems(double *first, double *second, struct Stack *stack1) {
	if (stack1->length<2){
		return 0;
	}
	else{
		*first = atof(stack1->item[stack1->length - 2]);
		*second = atof(stack1->item[stack1->length - 1]);
		//popItem(stack1);
		//popItem(stack1);
		return 1;
	}
}
//进行计算
double calculate(double first, double second, char op) {
	double answer=0.0;
	switch (op){
	case '+':
		answer = first + second;
		break;
	case '-':
		answer = first - second;
		break;
	case '*':
		answer = first * second;
		break;
	case '/':
		answer = first / second;
		break;
	case '^':
		break;
	default:
		break;
	}
	return answer;
}
//算数表达式放入Stack中(暂时测试用)
void putStringExpIntoStack(char *stringExp, struct Stack* stack,struct Stack* stack1) {
	int i = 0;
	int j = 0;
	double first = 0.0;
	double second = 0.0;
	double tempAnswer = 0.0;
	int n = strlen(stringExp);											//表达式内所有符号的数量
	char temp[STRING_MAX_LENGTH];										//temp数组
	char tempAnswerStr[STRING_MAX_LENGTH];
	char operateTemp[STRING_MAX_LENGTH];
	char charArrayExp[EXP_lENGTH];										//用字符数组承接字符串
	char *topStackchar;                                                 //栈顶操作符   
	for (i =0; i<n; i++){			
		charArrayExp[i] = *(stringExp++);
	}
	i = 0;
	while (i<n){
		if (isCharOrNum(charArrayExp[i]) == IS_CHAR) {
			temp[0] = charArrayExp[i];
			temp[1] = '\0';
			if (isEmpty(stack)==EMPTY){
				pushItme(stack, temp);										//如果是操作符号,则进操作符号栈内
			}
			else {
				topStackchar = topItem(stack);
				//如果操作栈外的大于等于操作栈内 则进操作栈
				if (compareOperator(topStackchar[0], charArrayExp[i])==SMALL_OR_EQUAL){
					temp[0] = charArrayExp[i];
					temp[1] = '\0';
					pushItme(stack, temp);
				}

				//如果操作栈栈内元素大于 则操作符出操作栈
				if (compareOperator(topStackchar[0], charArrayExp[i]) == BIG) {
					strcpy(operateTemp,topItem(stack));								//取得运算符号
					popItem(stack);
					//如果能计算则进行计算
					if (getTowItems(&first,&second,stack1)){				        //***如果从数字栈内可以取到数字元素的话
						tempAnswer = calculate(first, second, operateTemp[0]);     
						sprintf(tempAnswerStr, "%lf", tempAnswer);					//double转string
						if (operateTemp[0]!='('&&operateTemp[0]!=')'){
							popItem(stack1);
							popItem(stack1);
							pushItme(stack1, tempAnswerStr);
						}
					}
					while (isEmpty(stack) != EMPTY&&compareOperator(topStackchar[0], charArrayExp[i]) == BIG){
						strcpy(operateTemp, topItem(stack));
						popItem(stack);
						if (getTowItems(&first, &second, stack1)) {				       //如果从数字栈内可以取到数字元素的话
							tempAnswer = calculate(first, second, operateTemp[0]);      
							sprintf(tempAnswerStr, "%lf", tempAnswer);					//double转string
							if (operateTemp[0] != '('&&operateTemp[0] != ')') {
								popItem(stack1);
								popItem(stack1);
								pushItme(stack1, tempAnswerStr);
							}
						}
					}
					temp[0] = charArrayExp[i];
					temp[1] = '\0';
					pushItme(stack, temp);
				}
			}
			i++;
			continue;
		}
		if (isCharOrNum(charArrayExp[i]) == IS_NUM) {
			j = 0;
			temp[j] = charArrayExp[i];									//先把数字放在用于字符串处理的字符数组[0]里面
			j++;
			i++;
			while (i<n && isCharOrNum(charArrayExp[i]) == IS_NUM){	    //判断之后的字符是否还是数字,是的话则组合
				temp[j] = charArrayExp[i];
				j++;
				i++;
			}
			temp[j] = '\0';
			pushItme(stack1, temp);										//放入计算栈中
			continue;    
		}
	}
	while (isEmpty(stack) != EMPTY) {
		strcpy(temp, topItem(stack));
		popItem(stack);
		if (getTowItems(&first, &second, stack1)) {				       //如果从数字栈内可以取到数字元素的话
			tempAnswer = calculate(first, second, temp[0]);
			sprintf(tempAnswerStr, "%lf", tempAnswer);					//double转string
			if (temp[0] != '('&&temp[0] != ')') {
				popItem(stack1);
				popItem(stack1);
				pushItme(stack1, tempAnswerStr);
			}
		}
	}
}
int main(void) {
	char stringExp[EXP_lENGTH];											//算数表达式(中序表达式)
	struct Stack *stackOperate;										    //用于 中转 算数操作符的栈
	struct Stack *stackCalculate;										//用于进行算数计算的栈
	struct Operator operator_table[8] = {TABLE};
	stackOperate =(struct Stack*) malloc(sizeof(struct Stack));			//为栈分配一段内存空间
	stackCalculate = (struct Stack*) malloc(sizeof(struct Stack));		//为栈分配一段内存空间
	inntStack(stackOperate);
	inntStack(stackCalculate);
	printf("请输入一个算数表达式:(注意小括号要用英文的小括号不然不识别哦)\n");
	scanf("%s", &stringExp);											//输入一个算数表达式
	putStringExpIntoStack(stringExp, stackOperate,stackCalculate);
	//printf("这是符号栈:\n");
	//printStack(stackOperate);
	printf("--------------\n");
	//printf("这是数字栈:\n");
	printf("结果是:");
	printStack(stackCalculate);
	printf("--------------\n");
	getchar();
	getchar();
	return 0;
}


  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值