Calculator简易计算器


#include<stdio.h>
#include<windows.h>
#include<math.h>
#include<string.h>

int o_top = 0;//符号栈头
int num_top = 0;//数字栈头 

char o_s[100];//符号栈 
int num_s[100];//数字栈 

int jop(char o)//判断符号等级 judge_operator_priority
{
	if (o == '(')
		return 1;
	if (o == '+' || o == '-')
		return 2;
	if (o == '*' || o == '/')
		return 3;
	if (o == '^')
		return 4;
}

//操作符出栈 
void o_push(char o)
{
	o_top++;
	o_s[o_top] = o;
	return;
}

//操作数出栈 
void num_push(int n)
{
	num_top++;
	num_s[num_top] = n;
	return;
}

//自定义两元运算
//说明:operand1先进后出,operand2后进先出,所以运算的表达式应该为<operand1><oeprator><operand2> 
int math(int n1, int n2, char o)
{
	if (o == '+')
		return n1 + n2;
	if (o == '-')
		return n1 - n2;
	if (o == '*')
		return n1 * n2;
	if (o == '/' && n2 != 0)
		return n1 / n2;
	else if (o == '/' && n2 == 0)
	{
		printf("出错!\n");
		system("pause");
	}
	if (o == '^')
	{
		return pow(n1, n2);
	}
}

int main()
{
	printf("WB版计算器由于技术原因,仅支持以下运算....\n");
	//	Sleep(1500);
	printf("1.带括号的+-*/运算\n");
	//	Sleep(1500);
	printf("2.进制转换计算\n");
	//	Sleep(1500);
	printf("现在,请你输入“1”或“2”进行运算:\n");

	int choice;
	scanf_s("%d", &choice);


	/*
	当用户输入1时,进入4+1运算
	*/

	/*
	浅谈规则:
	1.操作符栈栈顶为空 或 栈顶操作符优先级<当前操作符 时,当前操作符入栈
	2.栈顶操作符优先级>目前操作符 且 数据栈至少有2个操作数 且 栈顶不为( 时,栈顶操作符出栈
	3.whlie循环次数是<而不是<= 的原因:最后出现x1(由这个while循环计算得到的数据)o x2(原表达式最后的操作数)
	4.每次运算后(调用了math函数后),将该次运算结果放回栈中(补到栈顶下面那个),然后再声明栈顶设其为0,进行栈顶--,使栈顶回到含有有效数据那
	*/
	if (choice == 1)
	{
		char str[100] = {0};//记录算式
		printf("Please enter the equation(no space):\n");
		int i = 0;
		gets(str);
		int size = strlen(str);
		while (i < size)
		{
			if (str[i] == '(')
			{
				o_push(str[i]);
				i++;
			}
			else if (str[i] >= '0' && str[i] <= '9')
			{
				int t = 0;
				while (str[i] >= '0' && str[i] <= '9' && i < size)
				{
					t = t * 10 + (str[i] - 48);
					i++;
				}
				num_push(t);
			}

			//+ -
			else if (str[i] == '+' || str[i] == '-')
			{
				if (o_top == 0 || jop(num_s[o_top]) == 1)
				{
					o_push(str[i]);
				}
				else if (jop(o_s[o_top]) == 2 || jop(o_s[o_top]) == 3 || jop(o_s[o_top]) == 4)
				{
					if (o_top >= 1 && num_top > 1 && jop(o_s[o_top]) != 1)
					{
						int n1 = num_s[num_top - 1];
						int n2 = num_s[num_top];
						num_s[num_top - 1] = math(n1, n2, o_s[o_top]);
						num_s[num_top] = 0;
						o_s[o_top] = '\0';
						num_top--; o_top--;
					}
					o_push(str[i]);
				}
				i++;
			}

			//* /
			else if (str[i] == '*' || str[i] == '/')
			{
				if (o_top == 0 || jop(o_s[o_top]) == 1 || jop(o_s[o_top]) == 2)
				{
					o_push(str[i]);
				}
				else if (jop(o_s[o_top]) == 2 || jop(o_s[o_top]) == 3)
				{
					if (o_top >= 1 && num_top > 1 && jop(o_s[o_top]) != 1)
					{
						int n1 = num_s[num_top - 1];
						int n2 = num_s[num_top];
						num_s[num_top - 1] = math(n1, n2, o_s[o_top]);
						num_s[num_top] = 0;
						o_s[o_top] = '\0';
						num_top--; o_top--;
					}
					o_push(str[i]);
				}
				i++;
			}

			// ^ 
			else if (str[i] == '^')
			{
				if (o_top == 0 || jop(o_s[o_top]) == 1 || jop(o_s[o_top]) == 2 || jop(o_s[o_top]) == 3)
				{
					o_push(str[i]);
				}
				else if (jop(o_s[o_top]) == 4)
				{
					if (o_top >= 1 && num_top > 1 && jop(o_s[o_top]) != 1)
					{
						int n1 = num_s[num_top - 1];
						int n2 = num_s[num_top];
						num_s[num_top - 1] = math(n1, n2, o_s[o_top]);
						num_s[num_top] = 0;
						o_s[o_top] = '\0';
						num_top--; o_top--;
					}
					o_push(str[i]);
				}
				i++;
			}

			// )
			else if (str[i] == ')')
			{
				do {
					int n1 = num_s[num_top - 1];
					int n2 = num_s[num_top];
					num_s[num_top - 1] = math(n1, n2, o_s[o_top]);
					num_s[num_top] = 0;
					o_s[o_top] = '\0';
					num_top--; o_top--;
				} while (jop(o_s[o_top]) != 1 && o_top >= 1 && num_top > 1);
				o_s[o_top] = '\0';
				o_top--;
				i++;
			}
		}
		//最后只剩下两个操作数和一个操作符,直接二元运算 
		while (o_top >= 1 && num_top > 1)
		{
			int n1 = num_s[num_top - 1];
			int n2 = num_s[num_top];
			num_s[num_top - 1] = math(n1, n2, o_s[o_top]);
			num_s[num_top] = 0;
			o_s[o_top] = '\0';
			num_top--; o_top--;
		}
		printf("%d", num_s[1]);
	}

	/*
	当用户输入2时,进行进制转换
	*/

	else if (choice == 2)
	{
		/*
		*  n进制转10进制
		*/
		int pr;//previous,先前的进制 
		int fn;//final,最后的进制
		int size;//用于测量长度 
		int i;
		int sum = 0;
		char ch[50] = "0";

		printf("即将输入三个数字,输入每个数字后,按回车转跳下一个输入内容......\n");
		printf("请输入原进制:");
		scanf_s("%d", &pr);
		printf("请输入原数据:");
		scanf_s("%s", &ch);
		printf("请输入想要转换成的数据的进制:");
		scanf_s("%d", &fn);

		size = strlen(ch);
		for (i = 0; i < size; i++)
		{
			int temp1 = pow(pr, size - i - 1);
			int temp2 = ch[i];
			switch (ch[i])
			{
			case 'A':
				sum += (temp2 - 55) * temp1;
				break;
			case 'B':
				sum += (temp2 - 55) * temp1;
				break;
			case 'C':
				sum += (temp2 - 55) * temp1;
				break;
			case 'D':
				sum += (temp2 - 55) * temp1;
				break;
			case 'E':
				sum += (temp2 - 55) * temp1;
				break;
			case 'F':
				sum += (temp2 - 55) * temp1;
				break;
			default:
				sum += (temp2 - 48) * temp1;
				break;
			}
		}

		/*
		*	10进制转n进制
		*/

		char ans[50] = "0";//答案存放 
		int j = 0;

		while (sum > 0)
		{
			switch (sum % fn)
			{
			case 10:
				ans[j] = 'A';
				break;
			case 11:
				ans[j] = 'B';
				break;
			case 12:
				ans[j] = 'C';
				break;
			case 13:
				ans[j] = 'D';
				break;
			case 14:
				ans[j] = 'E';
				break;
			case 15:
				ans[j] = 'F';
				break;
			default:
				ans[j] = (sum % fn) + 48;
				break;
			}
			j++;
			sum /= fn;
		}
		j--;
		for (; j >= 0; j--)
		{
			printf("%c", ans[j]);
		}
	}
	return 0;
}

文章作者: WB
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 WB !
  目录