指针进阶详解续---C语言

❤博主CSDN:啊苏要学习

  ▶专栏分类:C语言◀

  C语言的学习,是为我们今后学习其它语言打好基础,C生万物!

  开始我们的C语言之旅吧!✈

指针进阶详解续---C语言_第1张图片

目录

前言:

一.函数指针数组

二.指向函数指针数组的指针

三.回调函数

四.学习qsort


前言:

  上一篇我们讲了函数指针,这篇是函数指针数组等更多内容,最后我们学习一下qsort的使用,加强我们对函数指针的理解。

一.函数指针数组

  整型数组,是以整型为元素的数组,类似的,函数指针数组是存放函数指针的数组

  当我们拿到函数的地址,就能通过其地址调用该函数,现将多个函数地址存到数组里,实现一个计算器:

void menu()
{
	printf("****************************\n");
	printf("******* 1. Add 2. Sub ******\n");
	printf("******* 3. Mul 4. Div ******\n");
	printf("******* 0. Exit       ******\n");
	printf("****************************\n");
}
int main()
{
	int input = 0;
	int x = 0, y = 0, ret = 0;
	//第一个用NULL挤位置
	int(*pfarr[5])(int, int) = { NULL, Add, Sub, Mul, Div };
	do
	{
		menu();
		printf("请输入:>");
		scanf("%d", &input);
		if (input == 0)
		{
			printf("退出计算器\n");
			break;
		}
		else if (input >= 1 && input <= 4)
		{
			printf("请输入两个数:>");
			scanf("%d %d", &x, &y);
			ret = pfarr[input](x, y);
			printf("ret = %d\n", ret);
		}
		else
		{
			printf("输入错误,请重新输入\n");
		}
	} while (input);
	return 0;
}

  Add这些函数没打在代码里,读者知道即可,函数指针数组的存在,让一些代码变得很简洁。

  在以后如果需要添加新的计算方法,可以把函数指针加到数组中,改一改就可以正常使用啦。

二.指向函数指针数组的指针

  函数指针数组也是一个数组,也可以取地址,取出来的地址就可以存放到一个指针里,这个指针就叫函数指针数组的指针。

  之后的指针也可以放到数组里,就这样套娃,当然我们也不一定会用到,但我们要学,要知道,要会。

  这里我们来练习一个如何快速且正确写出类型:

int Add(int x, int y);
int main()
{
    //函数指针
    int(*pf)(int, int) = Add;
    
    //函数指针数组
    //1.把函数指针类型先搬下来
    //2.数组的话直接加[]
    int(*pfarr[5])(int, int) = {Add};

    //函数指针数组的指针
    //1.把函数指针数组类型搬下来
    //2.指针要加一颗*并用()包起来
    int(* (*ppfarr)[5])(int, int) = &pfarr;
    //注意:不能直接这样int((*ppfarr)[5])(int, int)
    //第一颗星是函数指针类型的 int(*)(int, int);
    return 0;
}

三.回调函数

  当A函数的地址作为参数传参给B函数,B函数使用这个地址调用A函数,A函数就是回调函数。
  回调函数不是实现方直接调用的,而是在特定条件发生时,由另一方调用,用来对该条件进行响应。

  函数指针的一个非常大的用途就是实现回调函数,回调函数的实现离不开函数指针的支持

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("ret = %d\n", ret);
}

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请输入:>");
		scanf("%d", &input);
		switch (input)
		{
		case 0:
			printf("退出计算器\n");
			break;
		case 1:
			Calc(Add);
			break;
		case 2:
			Calc(Sub);
			break;
		case 3:
			Calc(Mul);
			break;
		case 4:
			Calc(Div);
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

  这次使用函数指针方式实现这个计算器,Calc是一个函数,它的参数是一个函数指针,这样Calc就可以具有多个函数的功能

  当我们需要Calc实现什么功能,把对应函数的地址传进去,在Calc里面到特定的时候调用,这个通过函数指针调用的函数就叫回调函数。

四.学习qsort

  q是quick的意思,qsort--快排。和以前实现的bubble_sort相比,抛开效率这一点,冒泡排序只能实现整数的排序

  而qsort可以实现任意类型数据的排序,我们先查查文档,学习了解qsort如何使用,再模拟实现。

指针进阶详解续---C语言_第2张图片

  qsort是排序被base指向的数组里的num个元素,每个元素大小为size,比较的方法通过函数指针传参进去。

指针进阶详解续---C语言_第3张图片

  compar比较,p1是数组里a元素的地址,p2是数组里b元素的地址,如果p1指向的元素大于p2指向的,返回大于0的数;以及另外两种情况。

指针进阶详解续---C语言_第4张图片

  void*是无类型的指针,它可以接收任意数据类型的地址,但是不能对它解引用或指针加减运算,可以先强制类型转换再使用

  base数组和cmp参数设置成void*的目的是让函数能够具有普遍性

使用者可能传一个整型数组,也可能传一个浮点型数组,比较的元素也可能是不确定的,设置成空类型,就都可以接收而不会报警告。

指针进阶详解续---C语言_第5张图片

  对结构体中的字符串进行比较,上图是还未排序前的顺序,根据字母ASCII码值的大小排序应是:fa->hong->li->san

指针进阶详解续---C语言_第6张图片

  好啦,qsort如何使用也学完了,我们下篇就使用冒泡排序代替快速排序模拟实现一个可以排序任意类型的bsort

结语:希望读者读完有所收获!在学C的路上,祝福我们能越来越C!✔

  读者对本文不理解的地方,或是发现文章在内容上有误等,请在下方评论区留言告诉博主哟~,也可以对博主提出一些文章改进的建议,感激不尽!最后的最后!

  ❤求点赞,求关注,你的点赞是我更新的动力,一起努力进步吧。

你可能感兴趣的:(C语言,c语言,开发语言)