文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C语言超详细讲解指向函数的指针

2024-04-02 19:55

关注

一、函数的指针

首先,函数名代表函数的起始地址,调用函数时,程序会从函数名获取到函数起始地址,并从该地址起执行函数中的代码,函数名就是函数的指针,所以我们可以定义一个指向函数的指针变量,用来存放函数的起始地址,这样一来,就可以通过该变量来调用其所指向的函数。

二、指向函数的指针变量

定义指向函数的指针变量

返回值类型(* 指针变量名)(形参类型列表);

例如:int(*p)(int, int);,这行代码定义了一个可以指向返回值为整型且有两个整型形参函数的指针变量p,符合返回值为整型且有两个整型形参的函数都可以将其地址(即其函数名)赋给p。

使用指向函数的指针变量

在使用指向函数的指针变量时,只需要将函数名赋给指向函数的指针变量即可,因为函数名就是该函数的入口地址。

由于指向函数的指针变量保存了函数的地址,则该指针变量就指向了对应的函数。例如,求最大值的函数命名为max,如果将其函数名赋给指向函数的指针变量p(即p = max)后,则p就指向了max函数,并且可以通过(*p)(a, b);的方式来调用max函数,因为指针变量p保存了max函数的地址,那么*p就是max。需要注意的是,其中*p前的*可以省略,故也可以写成p(a, b);

三、调用函数的两种方式

引例:自定义max函数,求整数ab中的较大者并返回给主调函数,不考虑两数相等的情况通过函数名调用函数

#include <stdio.h>
int max(int, int); // max函数的函数声明
int main()
{
	int a, b;
	printf("请输入两个整数:");
	scanf("%d%d", &a, &b);
	printf("两数中的较大者的值为%d\n", max(a, b));
	return 0;
}
int max(int a, int b)
{
	if (a > b)
		return a;
	else
		return b;
}

通过指向函数的指针变量调用函数

#include <stdio.h>
int max(int, int); // max函数的函数声明
int main()
{
	int a, b;
	int(*p)(int, int); // 定义指向函数的指针p
	p = max; // p指向max函数
	printf("请输入两个整数:");
	scanf("%d%d", &a, &b);
	printf("两数中的较大者的值为%d\n", (*p)(a, b)); // (*p)(a, b) 也可写为 p(a, b)
	return 0;
}
int max(int a, int b)
{
	if (a > b)
		return a;
	else
		return b;
}

四、指向函数的指针的作用

看到这里有人可能会问,既然函数名就可以调用函数,为什么还要弄个奇奇怪怪的指针?这难道不是多此一举嘛?难倒是为了装13?不管怎样,使用指向函数的指针来调用函数肯定不是为了装13,主要的原因是:用函数名调用函数时比较死板,只能调用所指定的一个函数,而通过指针变量调用函数会比较灵活,可以根据不同的情况调用不同的函数。以下面的程序为例: 输入两个整数,然后让用户选择1或2,选1则调用max函数求出两个整数的较大者并将其输出,选2则调用min函数求出两个整数的较小者并将其输出,不考虑两数相等的情况

#include <stdio.h>
int max(int, int); // max函数的函数声明
int min(int, int); // min函数的函数声明
int main()
{
	int a, b, c, n;
	int (*p)(int, int); // 定义指向函数的指针p
	p = NULL; // 先将p赋为空
	printf("请输入两个整数:");
	scanf("%d%d", &a, &b);
	printf("输入1获取两个数中的较大者,输入2获取两个数中的较小者,请输入:");
	scanf("%d", &n);
	if (n == 1)
		p = max; // p指向max函数
	else if (n == 2)
		p = min; // p指向min函数
	c = p(a, b); // 调用p所指向的函数
	if (n == 1)
		printf("两个数中的较大者为:%d\n", c);
	else
		printf("两个数中的较小者为:%d\n", c);
	return 0;
}
int max(int a, int b)
{
	if (a > b)
		return a;
	else
		return b;
}
int min(int a, int b)
{
	if (a < b)
		return a;
	else
		return b;
}

五、用指向函数的指针作函数参数(重点)

指向函数的指针变量的一个重要用途是把函数的入口地址作为实参传递给其他函数。以下面的程序为例:

有两个整数ab,由用户输入1,2,3来决定进行什么操作。输入1则求出ab中的较大者,输入2则求出ab中的较小者,输入3则求出ab之和,不考虑两个数相等的情况

#include <stdio.h>
int fun(int, int, int (*p)(int, int));
int max(int, int);
int min(int, int);
int sum(int, int);
int main()
{
	int a = 34, b = -21, n;
	printf("输入1获得两数中的较大者,输入2获得两数中的较小者,输入3获得两个数的和,请输入:");
	scanf("%d", &n);
	if (n == 1)
		printf("两数中的较大者为%d\n", fun(a, b, max)); 
		// 向fun函数中传参时,只需要传入两个整数或整型变量以及想要在fun函数内执行的函数的函数名即可
		// 函数名会传递给对应的形参指针变量
	else if (n == 2)
		printf("两数中的较小者为%d\n", fun(a, b, min));
	else if (n == 3)
		printf("两个数的和为%d\n", fun(a, b, sum));
	return 0;
}
// fun函数的作用是获取最终结果
int fun(int x, int y, int (*p)(int, int))
{
	int result;
	result = p(x, y); // 用result接收最终结果,不管执行max,min,sum中的哪个函数,fun函数内部代码都不用改变
	return result;
}
int max(int x, int y)
{
	if (x > y)
		return x;
	else
		return y;
}
int min(int x, int y)
{
	if (x < y)
		return x;
	else
		return y;
}
int sum(int x, int y)
{
	return x + y;
}

从上面的程序中可以清晰地看出,不管调用maxminsum中的哪个函数,fun函数均没有任何变化,在fun函数内部的result只用来获取结果并将结果返回,但不去判断到底要通过哪个函数来计算这一结果,主调函数向其传入哪个函数,其内部就执行哪个函数。maxminsum函数用来计算,fun函数用来获取结果,这体现出了整个程序的模块化。

六、为什么要将指向函数的指针变量作为函数的形参(重点)

举一个例子,我们在学习数组的过程中,想要把数组中的所有元素输出,通常会接触一个新词,遍历。其实遍历的含义并不是将一个结构中的元素输出的过程,然而我在初学时便认为遍历等同于输出,这是我在初学时对遍历这个词不准确的理解,我相信也一定有人跟我一样这样认为。其实遍历指的是依次访问某种结构中的所有元素,至于对这些元素怎么操作,由程序员自己决定,比如,你想输出所有的元素,那就可以调用输出函数将每次获取到的元素输出;你想将所有元素的值翻倍,那就调用对应的翻倍函数将每次获取到的元素翻倍。但是这样一来,遍历函数的功能就变得十分单一,只能进行一种操作,要么是遍历并输出,要么是遍历并翻倍,如果在一个程序中,开始想要遍历并翻倍,后又想要遍历并输出,就只能定义两个函数来实现,但是我们发现不管对元素怎么操作,访问每个元素的代码都是相同,并且只要想对结构中的每个元素进行操作,首先要做的就是访问每个元素。但是如果为了输出而定义一个先遍历后输出的函数,为了将每个元素的值翻倍而定义一个先遍历后翻倍的函数,这样遍历元素的代码就是重复的。那要怎么办呢?既然遍历的操作是重复的,那我们就定义一个专门的遍历函数,该函数只用来访问元素,再定义其它多个操作数据的函数,至于我们对遍历后的数据执行什么样的操作,我们只需要将对应的操作函数通过遍历函数的形参接收过来,这样就可以实现在遍历函数中根据不同情况执行不同操作的目的,如此一来既体现出了程序设计的结构化与模块化,又减少了编程时的代码量。

到此这篇关于C语言超详细讲解指向函数的指针的文章就介绍到这了,更多相关C语言指向函数的指针内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯