编写C语言计算器:探索挑战与优化之路

如果你对C语言编程充满兴趣,那么构建一个简易计算器可能是一个很好的练习机会。在本文中,我们将探讨如何使用C语言实现一个基本的计算器,并分享我们在这个过程中遇到的挑战及其解决方案。

image.png

版本1.0

如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void menu()
{
	printf("########################\n");
	printf("#####1.Add 2.Sub  ######\n");
	printf("#####3.Mul 4.Div  ######\n");
	printf("########################\n");

}

int Add (int x, int y)
{
	return x + y;
}
int Sub(int x, int y)
{
	return x - y;
}
int Mul(int x, int y)
{
	return x *y;
}
int Div(int x, int y)
{
	return x /y;
}

int main()
{
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;
	do
	{
		menu();
		printf("请输入你的选择:");
		scanf("%d",&input);
		switch (input)
		{
		case 1:
			printf("请输入要计算的数字:");
			scanf("%d%d",&x,&y);
			ret = Add(x, y);
			printf("%d\n ",ret);
			break;
		case 2:
			printf("请输入要计算的数字:");
			scanf("%d%d", &x, &y);
			ret = Sub(x, y);
			printf("%d\n ", ret);
			break;
		case 3:
			printf("请输入要计算的数字:  ");
			scanf("%d%d", &x, &y);
			ret = Mul(x, y);
			printf("%d \n", ret);
			break;
		case 4:
			printf("请输入要计算的数字:");
			scanf("%d%d", &x, &y);
			ret = Div(x, y);
			printf("%d \n", ret);
			break;
		case 0:
			printf("退出\n");
			break;
		default:
			printf("输入错误,重新输入\n");
			break;
		}
	} while (input);



	return 0;
}

对于do…while的框架,我相信读者都已经比较熟悉了,如果还不熟悉的,可以去看看我之前的一篇关于
猜数字游戏的实现
我们放在vs2022中运行起来看一下效果:

image.png

这样一个只有加减乘除功能的简易计算器我们就实现了。这时我们发现,如果未来想要扩充这个计算器的功能,比如增加%,<< , >>, & , | , ^ 等功能,应该如何修正代码呢?

  1. 首先从当前的代码框架来看,我们需要修改菜单menu,添加必要的选项。
  2. 其次再switch中增加case5,case6…这样会导致switch过于”庞大“,逻辑不够清晰。

导致switch庞大的主要原因在于,每一个case语句中都有大量重复的语句。

  1. 基于此,我们将有两种优化方案,第二种涉及到回调函数的概念。请接着往下看:

版本2.0

思路:将switch语句替换成if…elseif语句
如下:(仅对主函数main修改即可)

int main()
{
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;
	do
	{
		menu();
		printf("请输入你的选择:");
		scanf("%d", &input);
		if (input >= 1 && input <= 4)
		{
			printf("请输入要计算的数字:");
			scanf("%d%d",&x,&y);
			ret = Add(x, y);    // 此处还需要进一步处理!!!
			printf("%d\n ",ret);
		}
		else if (input == 0)
		{
			printf("退出\n");
		}
		else
		{
			printf("重新输入\n");
		}
	} while (input);



	return 0;
}

这时我们发现,if语句中只能实现一个函数功能呀,怎么解决这个问题呢?我们能否**根据输入的input的值,调用不同的函数呢?**一个最容易想到的方法是,在if语句中套用选择语句来判断(即双层if),但是这样又时代码逻辑变得不清晰起来了,这显然违背了我们的初衷。我们可以借助函数指针数组来实现这一需求,请看:

image.png

啥?什么是函数指针数组?有的小伙伴可能不清楚,那现在让我来简单画个图解释一下把:

image.png

这下应该就理清楚它们之间的关系了把。
版本2.0完整代码如下:

int main()
{
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;
	int (*p[5])(int, int)= {0,Add,Sub,Mul,Div};
	do
	{
		menu();
		printf("请输入你的选择:");
		scanf("%d", &input);
		if (input >= 1 && input <= 4)
		{
			printf("请输入要计算的数字:");
			scanf("%d%d",&x,&y);
			ret = p[input](x, y);
			printf("%d\n ",ret);
		}
		else if (input == 0)
		{
			printf("退出\n");
		}
		else
		{
			printf("重新输入\n");
		}
	} while (input);



	return 0;
}

版本3.0

思路:我们依旧延用switch语句,将每一个case中的语句封装成一个函数
如下:

void Calc( int(* (*pf)[5])(int, int), int input)
{
	
	int x = 0;
	int y = 0;
	int ret = 0;
	printf("请输入要计算的数字:"); 
	scanf("%d%d", &x, &y);
	ret = (*pf)[input](x, y);
	printf("%d\n ", ret);
}
int main()
{
	int input = 0;
	int (*pfarr[5])(int, int) = { 0,Add,Sub,Mul,Div };
	/*int x = 0;
	int y = 0;
	int ret = 0;*/
	do
	{
		menu();
		printf("请输入你的选择:");
		scanf("%d",&input);
		switch (pfarr,input)
		{
		case 1:
			Calc(pfarr,input);
			break;
		case 2:
			Calc(pfarr,input);
			break;
		case 3:
			Calc(pfarr,input);
			break;
		case 4:
			Calc(pfarr,input);
			break;
		case 0:
			printf("退出\n");
			break;
		default:
			printf("输入错误,重新输入\n");
			break;
		}
	} while (input);



	return 0;
}

这样子,switch语句就不会因为增加功能而变得快速庞大了!
对于calc的第一个形参,有必要画图理解一下:

image.png

同样是3.0的思想,我们还可以在传参时稍作修改,得到下面这段代码:

void Calc(int (*pf)(int,int))
{

	int x = 0;
	int y = 0;
	int ret = 0;
	printf("请输入要计算的数字:");
	scanf("%d%d", &x, &y);
	ret = pf(x, y);
	printf("%d\n ", ret);
}
int main()
{
	int input = 0;
	int (*pfarr[5])(int, int) = { 0,Add,Sub,Mul,Div };
	/*int x = 0;
	int y = 0;
	int ret = 0;*/
	do
	{
		menu();
		printf("请输入你的选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			Calc(Add);
			break;
		case 2:
			Calc(Sub);
			break;
		case 3:
			Calc(Mul);
			break;
		case 4:
			Calc(Div);
			break;
		case 0:
			printf("退出\n");
			break;
		default:
			printf("输入错误,重新输入\n");
			break;
		}
	} while (input);

通过本文的学习,我们深入了解了用C语言实现简易计算器的过程,并探讨了在这个过程中遇到的一些常见问题及其解决方案。
希望本文能够对你在C语言编程中遇到类似问题时提供一些帮助和启发。如果你对本文中提到的任何主题有兴趣或疑问,不妨深入研究,相信你会有更多收获。

  • 28
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值