简单计算器(C 语言实现)

题目要求:

模拟简单运算器的工作。假设计算器只能进行加减乘除运算,运算数和结果都是整数,四种运算符的优先级相同,按从左到右的顺序计算。

输入格式:
输入在一行中给出一个四则运算算式,没有空格,且至少有一个操作数。遇等号”=”说明输入结束。

输出格式:
在一行中输出算式的运算结果,或者如果除法分母为0或有非法运算符,则输出错误信息“ERROR”。

输入样例:

1+2*10-10/2=

输出样例:

10

思路:

如何将等式的元素保存到数组中?

创建一个int数组,保存输入的等式元素。
不能对所有的元素都使用getchar()因为数字可能有多位。
因为每当读取一个运算符后(不包括‘=’),后面必定是一个数字,
所以可以每次读取并储存一个运算符后,
用scanf("%d",&equal[i])读取并储存一个数字。
这样就实现了将等式的所有元素都保存在等式数组中。
代码片段如下:

	int equal[100] = {0};					//建立等式数组
	int c;									//创建字符变量
	int i = 0, j, cnt;						//运算符指针, 右操作数指针, 计算次数
	int right;								//创建右操作数变量
	int tot;								//创建累积量

	scanf("%d", &equal[i]);					//先把第一个数字储存到等式数组中
	i++;									//让储存等式元素的数组的索引+1

	while( (c = getchar()) != '=')
	{
		equal[i] = c;						//读取运算符号
		i++;								//让储存等式元素的数组的索引+1
		scanf("%d", &equal[i++]);			//读取数字并让储存等式元素的数组的索引+1
											//(即不管读取的是数字还是符号都需要让索引+1)
		
		switch (c)							//如果读取了不是运算符号的字符,返回EORROR
		{
			case '+':
				break;
			case '-':
				break;
			case '*':
				break;
			case '/':
				break;
			default:
				printf("ERROR\n");
				return 0;
		}

		if (c == '/' && equal[i-1] == 0)	//如果被除数是0,返回ERROR
		{
			printf("ERROR\n");
			return 0;
		}
	}

如何利用等式数组进行从左向右的运算?

假设输入的字符串是1 + 2 * 10 - 10 / 2 =
通过上述保存等式数组的方法,得到的数组是:

元素1+2*10-10/2
索引012345678

p.s.所有的运算符都是通过ASCII码的形式储存的,是int型,想得到字符类型需要用到类型转化,即(char)equal[i]

通过观察可以发现
运算符的索引是奇数(2n +1 )
算子(我更喜欢叫操作数)的索引是偶数(2
n)。
于是我们可以建立一个累积变量(tot),让这个累计变量(tot)成为为运算的左操作数,元素中的每一个数字(除了第一个)成为右操作数。
e.g.

tot = 1i = 1; j = 2;
tot + 2 = 3 --> tot = 3n = 1;+ ----> equal(1) ; 2 ----> equal(2); i = 2 *n +1 = 3; n = n + 1 = 2; j = 2 * n = 4;
tot *10 = 30 --> tot = 30n = 2;* ----> equal(3) ; 10 ----> equal(4); i = 2 *n +1 = 5;n = n + 1 = 3; j = 2 * n =6 ;
tot - 10 = 20 --> tot = 20n = 3; + ----> equal(5) ; 2 ----> equal(6); i = 2 *n +1 = 7; n = n + 1 = 4; j = 2 * n = 8;
tot / 2 = 10 --> tot = 10n = 4; + ----> equal(7) ; 2 ----> equal(8); i = 2 *n +1 = 9; n = n + 1 = 5; j = 2 * n = 10;

代码片段如下:

int lene = i;							// lene ---> length of equal
	tot = equal[0];							// tot  ---> total(累加值)
	right = equal[2];						// right---> 右操作数(equal[0,2,4,6,8,...])

	for (i = 1, j = 2, cnt = 1; i < lene;)	// 计算等式(tot + or - or * or / equal[0,2,4,6,8,...])
	{
		switch ((char)equal[i])
		{
			case '+':
				//printf("hr+\n");
				tot += right;
				//printf("tot = %d\n",tot);
				break;
			case '-':
				//printf("hr-\n");
				tot -= right;
				//printf("tot = %d\n",tot);
				break;
			case '*':
				//printf("hr*\n");
				tot *= right;
				//printf("tot = %d\n",tot);
				break;
			case '/':
				//printf("hr/\n");
				tot /= right;
				//printf("tot = %d\n",tot);
				break;
		}

		i = 2 * cnt + 1;					// i是指向运算符号的指针,i = 1,3,5,7....
		cnt++;								// 计算的次数
		j = 2 * cnt;						// j是指向右操作数的指针, j = 2,4,6,8.....
		right = equal[j]; 
	}

最后tot的值即为等式的结果。

代码

#include <stdio.h>

int main()
{
	int equal[100] = {0};					//建立等式数组
	int c;									//创建字符变量
	int i = 0, j, cnt;						//运算符指针, 右操作数指针, 计算次数
	int right;								//创建右操作数变量
	int tot;								//创建累积量

	scanf("%d", &equal[i]);					//先把第一个数字储存到等式数组中
	i++;									//让储存等式元素的数组的索引+1

	while( (c = getchar()) != '=')
	{
		equal[i] = c;						//读取运算符号
		i++;								//让储存等式元素的数组的索引+1
		scanf("%d", &equal[i++]);			//读取数字并让储存等式元素的数组的索引+1(即不管读取的是数字还是符号都需要让索引+1)
		
		switch (c)							//如果读取了不是运算符号的字符,返回EORROR
		{
			case '+':
				break;
			case '-':
				break;
			case '*':
				break;
			case '/':
				break;
			default:
				printf("ERROR\n");
				return 0;
		}

		if (c == '/' && equal[i-1] == 0)	//如果被除数是0,返回ERROR
		{
			printf("ERROR\n");
			return 0;
		}
	}

	int lene = i;							// lene ---> length of equal
	tot = equal[0];							// tot  ---> total(累加值)
	right = equal[2];						// right---> 右操作数(equal[0,2,4,6,8,...])

	for (i = 1, j = 2, cnt = 1; i < lene;)	// 计算等式(tot + or - or * or / equal[0,2,4,6,8,...])
	{
		switch ((char)equal[i])
		{
			case '+':
				//printf("hr+\n");
				tot += right;
				//printf("tot = %d\n",tot);
				break;
			case '-':
				//printf("hr-\n");
				tot -= right;
				//printf("tot = %d\n",tot);
				break;
			case '*':
				//printf("hr*\n");
				tot *= right;
				//printf("tot = %d\n",tot);
				break;
			case '/':
				//printf("hr/\n");
				tot /= right;
				//printf("tot = %d\n",tot);
				break;
		}

		i = 2 * cnt + 1;					// i是指向运算符号的指针,i = 1,3,5,7....
		cnt++;								// 计算的次数
		j = 2 * cnt;						// j是指向右操作数的指针, j = 2,4,6,8.....
		right = equal[j]; 
	}

	printf("%d\n", tot);					//	打印出最后的计算值
	return 0;
}

  • 19
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值