指针传2(续集)

近期的天气是真的冷啊,老铁们一定要照顾好自己呀,注意防寒保暖,没有你们我怎么活啊!

上次的指针2的末尾,给大家分享了两个有趣的代码,今天就先来讲一讲那两个代码:

两个有趣的代码:

1  ( *  (   void  (*)    (  )   )   ) ( ); 
相同颜色的就是对应的一对括号,我们从里面看着出来,void  (*)  (  )这是一种指针类型吧,然后就是(   void  (*)    (  )   )   表示将0地址强制转换为函数指针类型,像我们之前写的(int)3.14这中就是强制类型转换,之后还剩下(*)(),这个不就是函数的调用吗?所以这是一次函数调用,将整数值0强制类型转换成一个函数地址,这个函数没有参数,返回类型为void;
去调用0地址处的函数.
void (*signal (int , void(*)(int) ) ) (int );
我们还是从里面分析着出来,首先看 signal (int , void(*)(int),这不就是一个函数吗?里面有两个参数,第一个是int类型,第二个是函数指针类型,该指针指向的函数参数是int,返回类型是void,signal函数的返回类型是这种类型的void(*)(int)函数指针,该指针指向的函数参数是int,返回类型是void,这是函数的声明!

函数指针数组:

函数指针数组是一个数组,其元素都是指向函数的指针。它的定义形式如下:

返回类型 (*指针数组名称[元素个数])(参数1类型, 参数2类型, ...);


其中,返回类型是函数的返回类型,指针数组名称是一个合法的标识符,元素个数是指针数组中元素的个数。参数类型是函数的参数类型。

例如,定义一个包含3个元素的函数指针数组,每个元素都指向返回类型为int,参数类型为int的函数,可以如下定义:
int (* PArray[3] )  (int);

PArray先和 [] 结合,说明 PArray是数组,数组的内容是 int (*)(int) 类型的函数指针。

这样,PArray就是一个包含3个元素的函数指针数组,每个元素都是指向返回类型为int,参数类型为int的函数的指针。

函数指针数组的使用:
我们编写计算器的实现:
先看看第一种方法:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

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;
}
void mune(void)
{
	printf("************************\n");
	printf("*****1,加法运算 ********\n");
	printf("*****2,减法运算 ********\n");
	printf("*****3,乘法运算 ********\n");
	printf("*****4,除法运算 ********\n");
	printf("*****0,退出计算 ********\n");
	printf("************************\n");

}
int main()
{
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;

	do
	{
		mune();
		printf("请选择:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("请输入两个操作数:\n");
			scanf("%d %d", &x, &y);
		    ret = Add(x, y);
			printf("%d\n", ret);
			break;
		case 2:
			printf("请输入两个操作数:\n");
			scanf("%d %d", &x, &y);
		    ret = Sub(x, y);
			printf("%d\n", ret);
			break;
		case 3:
			printf("请输入两个操作数:\n");
			scanf("%d %d", &x, &y);
			ret = Mul(x, y);
			printf("%d\n", ret);
			break;
		case 4:
			printf("请输入两个操作数:\n");
			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;
}

这种方法相信大家都会的吧,就是我们前面知识的应用,就不和大家细说了。上面我们看见重复的代码太多了,而且我们以后想实现其他的运算就会变得很麻烦。


上述的方法,我们可不可以把它们进行封装到另一个函数里面呢,通过函数指针找到相应的函数:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int input = 0;
int x = 0;
int y = 0;
int ret = 0;

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;
}

void mune(void)
{
	printf("************************\n");
	printf("*****1,加法运算 ********\n");
	printf("*****2,减法运算 ********\n");
	printf("*****3,乘法运算 ********\n");
	printf("*****4,除法运算 ********\n");
	printf("*****0,退出计算 ********\n");
	printf("************************\n");

}

void calc( int(*pf)(int, int))//函数指针
{
	printf("请输入两个操作数:\n");
	scanf("%d %d", &x, &y);
	ret = pf(x, y);
	printf("%d\n", ret);
}
int main()
{
	do
	{
		mune();
		printf("请选择:\n");
		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);
	
	return 0;
}

我们来看看运行效果:


我们可不可以把这些函数放在一个数组里面呢,因为这些函数都是这一大类的吧,弄一个函数指针数组,然后根据输入去调用相应的函数:

int (*parr[5]) (int, int) = { NULL,Add,Sub,Mul,Div };

前面加上一个空指针,这样我们在输入数字的时候就可以找到相应的函数(数组的下标是从0开始的)!

int main()
{
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;

	do
	{
		mune();
		printf("请选择:\n");
		scanf("%d", &input);
		int (*parr[5]) (int, int) = { NULL,Add,Sub,Mul,Div };
		//这里的函数指针数组我们称为转移表
		
		
			if (input == 0)
			{
				printf("退出计算器\n");
				
			}
			else if(input>=1 && input<=4)
			{
			    printf("请输入两个操作数:\n");
			    scanf("%d %d", &x, &y);
		        ret = parr[input](x, y);
			    printf("%d\n", ret);
			    
			}
			else
			{
				printf("输入错误,请重新输入!\n");
			
			}
		
	} while (input);

	return 0;
}

这样我们是不是就大大减少了我们的代码量了,而且如果想加上其他的方法,加在数组里面就可以了,但这只是其中一部分代码哈,前面的方法我没有写上。

好了,今天就到这里了,明天见哦,不要太想我哟!😊😊😊


 

  • 22
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

并不会

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值