C语言课程设计-简易计算器

1.题目算术表达式求值

功能输入一个整数算术表达式字符串,分解出数值及运算符,并计算  输出结果。

要求:利用菜单可以循环实现求出加法、减法、乘法、除法算术表达式。

  进一步要求*: 

(1) 能够实现连续运算;             比如:123+233+555+666=

(2) 能够实现混合运算;             比如:120-23*5-20/4=

(3) 能够实现带括号的混合运算运算。 比如:12*(234-5)+(23+7)= 

(4) 能够实现实数的各类运算。       比如:12.23*(12-3.7)+12.56=

(5) 能够实现多层括号嵌套运算     …(….(..)….(..(…))…)…

 

对不带括号的表达式容易计算,但是不要忽略除数为0的情况,此时表达式错误。对多括号的表达式可以用递归处理,也可以用数组模拟栈的方式进行解决,本代码对多层括号的表达式处理使用数组模拟栈的方式,带括号的简单混合运算则使用类似递归的方式,实际上本代码可以再简洁,直接全部用模拟栈的方式满足题目所有功能。

#include 
#include 
#include  
#include 
const int MAX_SIZE = 2019;
//存储操作数的栈 
double stack_n[MAX_SIZE]; int t_n;
//存储运算符的栈
char stack_c[MAX_SIZE]; int t_c; 

//函数声明 
void add();		//减法 
void sub();		//减法 
void divi();	//除法 
void muli();	//乘法 
void mix();		//混合运算(不带括号) 
				//混合运算(带括号) 
double mix_1();	
void mix_plus();

//实数多括号 括号嵌套 运算
bool check(char );			//检查是否为运算符 
char cmp(char , char );		//比较运算符之间的优先级 
double cacu(double , char , double );	//进行相应运算符和操作数的运算 
void fun();					//主要功能函数 
		 
int main() {
	while(1) {
		printf ("                   菜单\n"); 
		printf ("*************************************************\n");
		printf ("#  	1. 整数加法运算                         #\n");
		printf ("#  	2. 整数减法运算                         #\n");
		printf ("#  	3. 整数除法运算                         #\n");
		printf ("#  	4. 整数乘法运算                         #\n");
		printf ("#  	5. 整数混合运算                         #\n");
		printf ("#  	6. 整数带括号混合运算                   #\n");
		printf ("#  	7. 实数多括号混合运算                   #\n"); 
		printf ("#  	0. 退出                                 #\n");
		printf ("*************************************************\n");
		printf ("请输入:");
		int k;
		scanf ("%d", &k);
		while (k < 0 || k > 7) {
			printf ("选择错误,请重新输入:");
			scanf ("%d", &k);
		}
		getchar();
		switch(k) {
			case 0: exit(0);
			case 1: {
				//清屏函数 
				system("cls");
				add(); break;
			}
			case 2: {
				system("cls");
				sub(); break;
			}
			case 3: {
				system("cls");
				divi(); break;
			}
			case 4: {
				system("cls");
				muli(); break;
			}
			case 5: {
				system("cls");
				mix(); break;
			}
			case 6: {
				system("cls");
				mix_plus(); break;
			}
			case 7: {
				system("cls");
				fun(); break;
			} 
		}
	}
	
	return 0;
}

//连续加法
void add() {
	while(1) {
		printf ("请输入加法表达式:\n");
		char c; 
		int sum = 0;
		while((c = getchar())!= '\0') {
			int a = 0;
			//一直读数字直到非数字 
			while ('0' <= c && c <= '9') {
				a = a * 10 + (c - '0');
				c = getchar();
			}
			//将数字相加 
			sum += a;
	
			if ( c == '=') break;
		}
		printf ("%d\n", sum);
		printf ("继续请输入y或Y,输入其它返回菜单.\n");
		getchar();c = getchar(); 
		if (c != 'y' && c != 'Y') break;
	}
	system("cls"); 
} 

//连续减法
void sub() {
	while (1) {
		printf ("请输入减法表达式:\n");
		char c; 
		int sum = 0, flag = 0;
		while((c = getchar())!= '\0') {
			int a = 0;
			//处理第一个数为负数的情况 
			if (c == '-') flag = 1;
			while ('0' <= c && c <= '9') {
				a = a * 10 + (c - '0');
				c = getchar();
			}
			if (flag) a = -a, flag = 0;
			sum += a;
			if ( c == '=') break;
			//将减数变为负数,然后与被减数相加处理 
			else if (c == '-') flag = 1; 
		}	
		printf ("%d\n", sum);
		printf ("继续请输入y或Y,输入其它返回菜单.\n");
		getchar(); c = getchar(); 
		if (c != 'y' && c != 'Y') break;
	}
	system("cls");
} 

//连续乘法
void muli() {
	while(1) {
		printf ("请输入乘法表达式:\n");
		char c; 
		//flag = 1表示该数为负数 
		int sum = 1, flag = 0;
		while((c = getchar())!= '\0') {
			int a = 0, k = 0; 
			if (c == '-') flag = 1;
			//读入数字 
			while ('0' <= c && c <= '9') {
				a = a * 10 + (c - '0');
				k = 1;
				c = getchar();
			}
			if (flag) a = -a, flag = 0;
			if (k) sum *= a;
			if ( c == '=') break;
			else if (c == '-') flag = 1; 
		}
		printf ("%d\n", sum);
		printf ("继续请输入y或Y,输入其它返回菜单.\n");
		getchar(); c = getchar(); 
		if (c != 'y' && c != 'Y') break;
	}
	system("cls");
} 

//连续除法
void divi() {
	while(1) {
		printf ("请输入除法表达式:\n");
		char c; 
		//flag = 1 表示该数为负数 
		double sum = 0, flag = 0; 
		while((c = getchar()) != '\0') {
			//k = 1表示读取了数字,防止第一个数为负数时进行错误运算 
			int a = 0, k = 0;
			if (c == '-') flag = 1;
			while ('0' <= c && c <= '9') {
				a = a * 10 + (c - '0');
				k = 1;
				c = getchar();
			}
			if (flag) a = -a, flag = 0;
			//若读入第一个数,使sum = a 
			if (!sum && k) sum = a * 1.0;
			//不是第一个数时 
			else if (k) {
				//a为0的情况 
				if (a == 0) {
					printf ("表达式错误!\n");
					return;
				}
			sum /= (double)a;
			}
		
			if ( c == '=') break;
			else if (c == '-') flag = 1; 
		}
		
		printf ("%.2lf\n", sum);
		printf ("继续请输入y或Y,输入其它返回菜单.\n");
		getchar(); c = getchar(); 
		if (c != 'y' && c != 'Y') break;
	} 
	system("cls");
} 


//混合运算
void mix() {
	while(1) {
		printf ("请输入混合运算表达式:\n");
		char c; 
		//p = 1,运算符为"*",p = -1,运算符为"/" 
		int flag = 0, p = 0;
		double temp, sum = 0; 
		while((c = getchar())!= '\0') {
			int a = 0, k = 0;
			if (c == '-') flag = 1;
			while ('0' <= c && c <= '9') {
				a = a * 10 + (c - '0');
				k = 1;
				c = getchar();
			}
			if (flag) a = -a, flag = 0;
			
			
			if (c == '-') flag = 1;
			//当前运算符为"*" 
			else if (c == '*' && k) {
				//状态标志位0 
				if (!p) p = 1, temp = (double)a;
				//前一个运算符为"/" 
				else if (p == -1) {
					if (!a)	{printf ("表达式错误!\n"); return;}
					temp /= a, p = 1; 
				}
				//前一个运算符为"*" 
				else temp *= a, p = 1;
			}
			//当前运算符为"/" 
			else if (c == '/' && k) {
				//状态标志位0 
				if (!p) p = -1, temp = (double)a;
				//前一个运算符为"*" 
				else if (p == 1) temp *= a, p = -1;
				//前一个运算符为"/" 
				else {
					if (!a)	{ printf ("表达式错误!\n"); return;}
					temp /= a, p = -1;
				}
			}
			//遇到优先级低的运算符时,进行运算并重置p 
			if ((c == '+' || c == '-' || c == '=') && p == 0 && k)		sum += a;
			else if ((c == '+' || c == '-' || c == '=') && p == 1 && k)	sum += temp * a, p = 0;
			else if ((c == '+' || c == '-' || c == '=') && p == -1 && k) {
				if (a != 0) sum += temp / a, p = 0;
				else {	printf ("表达式错误!\n"); return;}
			}
			
			if (c == '=') break;
		}
		//输出结果 
		printf ("%.2lf\n", sum);
		printf ("继续请输入y或Y,输入其它返回菜单.\n");
		getchar(); c = getchar(); 
		if (c != 'y' && c != 'Y') break;
	}
	system("cls");
} 
//处理括号内的运算 
double mix_1(){
	char c; 
	int flag = 0, p = 0;
	int temp, sum = 0; 
	while((c = getchar())!= ')') {
		int a = 0, k = 0;
		if (c == '-') flag = 1;
		while ('0' <= c && c <= '9') {
			a = a * 10 + (c - '0');
			k = 1;
			c = getchar();
		}
		if (flag) a = -a, flag = 0;
		
		
		if (c == '-') flag = 1; 
		else if (c == '*' && k) {
			if (!p) p = 1, temp = (double)a;
			else if (p == -1) {
				//if (!a)	{printf ("表达式错误!\n"); return;}
				temp /= a, p = 1; 
			}
			else temp *= a, p = 1;
		}
		else if (c == '/' && k) {
			if (!p) p = -1, temp = a;
			else if (p == 1) temp *= a, p = -1;
			else {
				//if (!a)	{ printf ("表达式错误!\n"); return;}
				temp /= a, p = -1;
			}
		}
		
		if ((c == '+' || c == '-' || c == ')') && p == 0 && k)		sum += a;
		else if ((c == '+' || c == '-' || c == ')') && p == 1 && k)	sum += temp * a, p = 0;
		else if ((c == '+' || c == '-' || c == ')') && p == -1 && k) {
			if (a != 0) sum += temp / a, p = 0;
			//else {	printf ("表达式错误!\n"); return;}
		}
		if (c == ')') break;
	}
	return sum;
}

//带括号混合运算
void mix_plus() {
	while(1){ 
		printf ("输入整数带括号的混合运算表达式:\n");
		char c; 
		int flag = 0, p = 0;
		double temp, sum = 0; 
		while((c = getchar())!= '\0') {
			double a = 0;
			int k = 0;
			if (c == '-') flag = 1;
			//读到"("调用函数计算 
			else if (c == '(') {
				a = mix_1(), k = 1;
				c = getchar();
				//printf("%d\n",a);
			}
			while ('0' <= c && c <= '9') {
				a = a * 10 + (c - '0');
				k = 1;
				c = getchar();
			}
			if (flag) a = -a, flag = 0;
			
			
			if (c == '-') flag = 1; 
			else if (c == '*' && k) {
				if (!p) p = 1, temp = a;
				else if (p == -1) {
					if (!a)	{printf ("表达式错误!\n"); return;}
					temp /= a, p = 1; 
				}
				else temp *= a, p = 1;
			}
			else if (c == '/' && k) {
				if (!p) p = -1, temp = a;
				else if (p == 1) temp *= a, p = -1;
				else {
					if (!a)	{ printf ("表达式错误!\n"); return;}
					temp /= a, p = -1;
				}
			}
			
			if ((c == '+' || c == '-' || c == '=') && p == 0 && k)		sum += a;
			else if ((c == '+' || c == '-' || c == '=') && p == 1 && k)	sum += temp * a, p = 0;
			else if ((c == '+' || c == '-' || c == '=') && p == -1 && k) {
				if (a != 0) sum += temp / a, p = 0;
				else {	printf ("表达式错误!\n"); return;}
			}
			
			if (c == '=') break;
		}
		printf ("%.2lf\n", sum);	
		printf ("继续请输入y或Y,输入其它返回菜单.\n");
		getchar(); c = getchar(); 
		if (c != 'y' && c != 'Y') break;
	} 
	system("cls");
}

void fun() {
	while (1) {
		//重置栈 
		memset(stack_n, 0, sizeof(stack_n));
		memset(stack_c, 0, sizeof(stack_c));
		t_c = t_n = 0;
		char str[2020];
		printf ("输入实数混合运算表达式:\n");
		scanf("%s", str);		//获取表达式

		double a, b;	
		int i = 0, count = 0, flag = 0;	//count对小数位数计数, flag = 1表示负号 
		char c = str[i]; 		//记录i的上一个字符,i = 0时等于自身 
		
		stack_c[++t_c] = '=';	//便于比较 
		while (str[i] != '=' || stack_c[t_c] != '=') {
			//若不是操作数 
			if (!check(str[i])) {
				//如果上一个字符是小数点 
				if (c == '.') count++;
				//count > 0 进行有关小数的计算 
				if (count > 0) {
					//取栈顶元素并出栈 计算后入栈 
					a = stack_n[t_n--];
					if (a < 0)	//负数 
						stack_n[++t_n] = a - (str[i] - '0') / pow(10, count);
					else 
						stack_n[++t_n] = a + (str[i] - '0') / pow(10, count);
					count++; 
				} 
				//有关整数 
				if (str[i] != '.' && !count) {
					//若上一个字符是数字且操作数栈不为空 
					if (!check(c) && t_n > 0) {
						a = stack_n[t_n--];
						if (a < 0)	//负数 
							stack_n[++t_n] = a * 10 - (str[i] - '0');
						else 
							stack_n[++t_n] = a * 10 + str[i] - '0';
					} 
					else {
						if (flag) 
							stack_n[++t_n] = -(str[i] - '0');
						else 
							stack_n[++t_n] = str[i] - '0';
						flag = 0;
					}
				}
				c = str[i++]; //字符数组下标移动并保存上一个字符 
			} 
			else 
			{
				count = 0;  //重置
				//检查负数情况 
				if (check(c) && str[i] == '-') {
					flag = 1; c = str[i++];
					continue;
				} 
				//运算符之间的比较和相应操作 
				switch (cmp(stack_c[t_c], str[i])) {
					case '>':{ //当前运算符优先级低 取出栈顶运算符和操作数前两个数(两次出栈)进行运算,将结果入操作数栈
								//然后再次与栈顶运算符比较直到遇见"=" 或 "<" 情况 
						char  op = stack_c[t_c--]; 
		                a = stack_n[t_n--]; b = stack_n[t_n--];
		                //表达式错误 
		                if (a == 0 && op == '/') {
		                	printf ("表达式错误!\n");
		                	return;
						} 
						stack_n[++t_n] = cacu(b, op, a);	  
						break;
					}
					case '=':{  //此时'(' == ')' 取出左括号 
						t_c--; 
						c = str[i++];
						break;
					}
					case '<':{	//优先级比栈顶运算符高,入栈 
						stack_c[++t_c] = str[i];
						c = str[i++];
						break;
					}
				} 
			} 
		} 
		//输出结果 
		printf ("%.4lf\n", stack_n[t_n]);
		printf ("继续请输入y或Y,输入其它返回菜单.\n");
		getchar(); c = getchar();
		if (c != 'y' && c != 'Y') break;
	}
	system("cls");
}

bool check(char c) {
	//包含运算符的字符数组 
	char oper[7] = {'+','-','*','/','(',')','='}; 
	for (int i = 0; i < 7; i++) {
		//与字符c比较相等返回true否则循环结束返回false 
		if (oper[i] == c) return true;
	}
	return false;
}

char cmp(char x, char y) {
	char c;
	switch (x) {
		case '+':
		case '-':{ 
			switch(y) {
				case '+':
				case '-':
				case ')':
				case '=':
					c = '>'; break;
				default: c = '<'; break;
			}
			break;
		}
		case '*':
		case '/':{
			switch(y){
				case '(':
					c = '<'; break;
				default: c = '>';
			}
			break;
		}
		case '(':{
			switch(y){
				case ')':
					c = '='; break;
				default: c = '<';
			}
			break;
		}
		case ')':{
			c = '>';
			break;
		}
		case '=':{
			switch(y){
				case '=':
					c = '='; break;
				default: c = '<';
			}
			break;
		}
	}
	return c;
}

double cacu(double a, char op, double b) {
	double sum;
	switch(op) {
		case '+':
			sum = a + b; break;
		case '-':
			sum = a - b; break;
		case '*':
			sum = a * b; break;
		case '/':
			sum = a / b; break;
	}
	return sum;
}

 

你可能感兴趣的:(C语言)