广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言函数指针的老生常谈
  • 168
分享到

C语言函数指针的老生常谈

2024-04-02 19:04:59 168人浏览 独家记忆
摘要

目录函数指针函数指针的应用函数指针作为参数实例(qsort函数)总结 函数指针 本质上是一个指针,只不过指向函数而已。 编译器在编译期间对函数开辟了一块空间,而这快空间的开始地址,就

函数指针

本质上是一个指针,只不过指向函数而已。

编译器在编译期间对函数开辟了一块空间,而这快空间的开始地址,就是它的函数指针 。

下面我们也直接用最直观的程序来了解函数指针:


#if 1
void func()
{
	printf("hello ptr!");
}
int main()
{
	void (*p)();
	p = func;
	p();
}
#endif

在这里我们给出了func()函数,并在其中打印hello ptr! 。在这里,我们定义了一个函数指针p,大家会发现他的定义语句十分的奇特: void (*p)() ,其实与int a,float b……十分的类似,定义嘛,实际上也就是给出类型,给出变量名,在这里void (*p)() 给出的类型是指向返回值为void 无参数传入的函数 ,在这里我们把这个指针命名为p。

这条程序中,我们直接将与p类型相对应的函数func()的地址func赋值给p,于是我们便能拿着p去做func的事情了。

换言之,如果我们需要定义一个指向返回值为double,有一个int型参数a,一个long型参数b,名称为f_ptr的函数指针呢?

那么显然便是: double (*f_ptr)(int a,long b)

但其实因为我们只需要告诉编译器我们的函数指针指向的是一个什么类型的函数,所以参数名并不是必须的只需告诉他是什么类型即可,所以我们还可以简写为 double (*f_ptr)(int , long)

我们还要注意到一个小细节:

标准规定:函数名,可以认为是其开始地址

所以函数指针p获取函数地址: p = &Max; == p = Max;

函数指针p怎么调用: (*p)(10,20); == p(10,20);

我们同样能够拿上述程序来做个实验:

函数指针的应用

函数指针在我们程序中最常见的应用其实应该是作为函数的参数。比如,我们可以这样:


int Add(int a, int b)  //加法实现
{
	return a + b;
}
int Sub(int a, int b)  //减法实现
{
	return a - b;
}
int Mul(int a, int b)  //乘法实现
{
	return a * b;
}
int Div(int a, int b)  //除法实现
{
	if (b == 0)
		return -1;
	return a / b;
}
int Computer(int a, int b, int(*p)(int, int))   //模板函数
{
	return p(a, b);
}
int main()
{
	printf("a+b=%d\n", Computer(10, 20, Add));
	printf("a-b=%d\n", Computer(10, 20, Sub));
	printf("a*b=%d\n", Computer(10, 20, Mul));
	printf("a/b=%d\n", Computer(10, 20, Div));
	return 0;
}

在这里,我们做出了一个模板函数computer,在他的参数列表中,我们给出了int (*p)(int,int)的参数,我们调用函数的时候需要给到这个函数一个函数指针,而我们也在模板函数中使用了函数指针来调用具体函数。

我们定义了Add、Sub、Mul、Div四个具体的实现函数,用来实现相应的加减乘除,而computer只需要接受具体的函数指针来决定他需要干什么,这样为程序的可拓展性提供了非常大的帮助,我们不需要在想要增删功能的时候修改主要代码,仅需增删具体的功能函数就行,甚至部分库函数利用函数指针作为参数的优点来为我们提供可自定义的功能,下面也用一个例子来解释。

函数指针作为参数实例(qsort函数)

qsort函数包含在<stdlib.h>库中

qsort函数的原型描述为:

void qsort( void *base, size_t n_elements, size_t el_sizeint ,int (*compar) (void const * , void const * ) )

qsort函数其实是C语言为我们编写好的一个快速排序函数,他通过函数指针为我们开放了一定的自定义功能

各参数解析,base中传入需要排序的数组,n_elements为该数组中元素的个数,el_sizeint为数组各元素的大小,而compar,则是我们今天反复提及的函数指针,在这里可以理解成为数组内各元素的比较规则。

干说可能很难理解,直接上程序:


int compare_int(const void* a,const void* b)  //用于比较两个整型值的具体函数
{
	//将函数传入的参数进行强转
	int _a = *(const int*)a;
	int _b = *(const int*)b;
	//不相等
	if (_a > _b)
		return 1;
	else if (_a < _b)
		return -1;
	//相等
	else
		return 0;
}
int main()
{
	int arr[] = { 1,3,5,7,2,4,6,7,10,9,8 };
	qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), compare_int);
	for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
		printf("%d ", arr[i]);
	return 0;
}

此程序中,我们定义了自己的比较规则compare_int函数,传入到qsort函数的最后一个参数,其余参数正常传入,排序成功!

(qsort函数的比较规则默认返回1则第一个参数大于第二个参数,返回-1则反之,返回0则传入的两个参数相等)

在这里强转是必须的,因为默认传入的是两个const void*类型,这在程序中是无法进行比较的。

同时,参数的类型也必须都写为const void* 因为在qsort函数声明中明确表示传入的函数指针应为返回值为int,两个参数都为const void*类型,自定义比较规则函数的参数类型若不为const void*则会造成函数类型不匹配的问题。

我们在这里也不妨想想一个字符串的指针数组应该如何写出我们的自定义函数来排序呢?


int compare_string(const void* _str1, const void* _str2)
{
	//强转类型
	const char* str1 = *(const char**)_str1;
	const char* str2 = *(const char**)_str2;
	//利用string.h库中stramp函数(返回值契合qsort函数比较规则)来进行比较
	int tem = strcmp(str1, str2);
	return tem;
}
int main()
{
	const char* arr[] = { "abc","dsa","adfw","odc","adsfa","afsd" };
	qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(const char*), compare_string);
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]);i++)
		printf("%s ", arr[i]);
	return 0;
}

可能在这大家疑惑的地方在于为什么需要使用一个二级指针来进行强转,其实在这里可以用我们平时的指针参数传入来理解,比如void func(int* a),我们传入给这个带*参数时实际上传入的是a的地址。

同理我们传入_str的是什么?我们原数组是一个指针数组,每个元素本质上是个一级指针,那么我们每次比较时传入给compare_string函数一个带*的参数,是不是那便是一级指针的地址,即二级指针,加上一个解引用的*变回一级指针便可以赋给str1了。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: C语言函数指针的老生常谈

本文链接: https://www.lsjlt.com/news/158237.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C语言函数指针的老生常谈
    目录函数指针函数指针的应用函数指针作为参数实例(qsort函数)总结 函数指针 本质上是一个指针,只不过指向函数而已。 编译器在编译期间对函数开辟了一块空间,而这快空间的开始地址,就...
    99+
    2022-11-12
  • 老生常谈C语言中指针的使用
    目录前提一.指针基础1.1 变量指针1.2 数据指针1.3 指针的本质1.4 指针数组1.5 指针的移动1.5 Scanf函数的解释二.指针的进阶玩法2.1 二维指针2.2 结构体指...
    99+
    2022-11-13
  • 老生常谈C语言链表小结
    目录链表的概念及结构概念结构链表的分类单链表的实现(无头)双向链表的实现总结:链表和顺序表的区别链表的概念及结构 概念 链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的...
    99+
    2022-11-12
  • C语言的数组指针与函数指针详解
    目录前言函数指针语法数组指针与指针数组总结前言 数组指针和函数指针都是C语言比较难的知识点,尤其是函数指针,并且函数指针在开发中有着巨大的作用。 函数指针语法 定义一个函数指针,并通...
    99+
    2022-11-13
  • C语言函数指针详解
    目录Introduction函数指针 Function PointersExercise 1:qsort中的函数指针Exercise 2:总结Introduction 上一个lab的...
    99+
    2022-11-12
  • C语言中怎么使用指针函数和函数指针
    本篇内容介绍了“C语言中怎么使用指针函数和函数指针”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、指针函数当一个函数声明其返回值为一个指针...
    99+
    2023-06-16
  • C语言中如何使用指针函数和函数指针
    这篇文章给大家介绍C语言中如何使用指针函数和函数指针,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、指针函数当一个函数声明其返回值为一个指针时,实际上就是返回一个地址给调用函数,以用于需要指针或地址的表达式中。格式:...
    99+
    2023-06-17
  • C语言函数指针怎么用
    这篇文章主要介绍“C语言函数指针怎么用”,在日常操作中,相信很多人在C语言函数指针怎么用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言函数指针怎么用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!定义...
    99+
    2023-06-22
  • 如何理解C语言函数传参:指针的指针
    这篇文章主要介绍“如何理解C语言函数传参:指针的指针”,在日常操作中,相信很多人在如何理解C语言函数传参:指针的指针问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解C语言函数传参:指针的指针”的疑惑有所...
    99+
    2023-06-15
  • C语言函数的参数使用指针
    在c语言中实参和形参之间的数据传输是单向的“值传递”方式,也就是实参可以影响形参,而形参不能影响实参。指针变量作为参数也不例外,但是可以改变实参指针变量所指向的变量的值。 #in...
    99+
    2022-11-12
  • C语言如何使用数组指针与函数指针
    这篇文章主要为大家展示了“C语言如何使用数组指针与函数指针”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C语言如何使用数组指针与函数指针”这篇文章吧。函数指针语法定义一个函数指针,并通过函数指针...
    99+
    2023-06-29
  • C语言中指针常量和常量指针的区别
    在面试中我们经常会被面试官问到什么是常量指针,什么又是指针常量。 指针常量就是指针本身是常量,指针里面所存储的内容(内存地址)是常量,不能改变。但是,对应内存地址里存的内容是可以通过...
    99+
    2022-11-12
  • C语言指向函数的指针实例分析
    这篇文章主要介绍“C语言指向函数的指针实例分析”,在日常操作中,相信很多人在C语言指向函数的指针实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言指向函数的指针实例分析”的疑惑有所帮助!接下来,请跟...
    99+
    2023-07-02
  • C语言返回值指针的函数详解
          #include<stdio.h> void main() { int a[5] = { 1,3,5,7,9 }; ...
    99+
    2022-11-13
  • C语言详解函数与指针的使用
    目录一、函数类型二、函数指针三、回调函数四、小结一、函数类型 C 语言中的函数有自己特定的类型 函数的类型由返回值,参数类型和参数个数共同决定,如 int add(int i, in...
    99+
    2022-11-13
  • C语言超详细讲解指向函数的指针
    目录一、函数的指针二、指向函数的指针变量三、调用函数的两种方式四、指向函数的指针的作用五、用指向函数的指针作函数参数(重点)六、为什么要将指向函数的指针变量作为函数的形参(重点)一、...
    99+
    2022-11-13
  • c语言指针在函数中怎么使用
    在C语言中,指针在函数中的使用有以下几种方式:1. 将指针作为函数参数传递:可以将指针作为函数的参数传递给函数,这样函数内部就可以通...
    99+
    2023-10-20
    c语言
  • C语言深入浅出分析函数指针
    我们先看一个代码: #include<stdio.h> void test() { printf("haha\n"); } int main() { printf("...
    99+
    2022-11-13
  • c语言怎么向函数传递数组指针
    在C语言中,可以通过指针的方式向函数传递数组指针。以下是一个示例代码: #include void printArray(int...
    99+
    2023-10-25
    c语言
  • C语言中指针常量和常量指针的区别是什么
    这篇文章主要介绍了C语言中指针常量和常量指针的区别是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C语言中指针常量和常量指针的区别是什么文章都会有所收获,下面我们一起来看看吧。在面试中我们经常会被面试官问到...
    99+
    2023-06-26
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作