ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

C语言-指针函数与函数指针及回调函数的使用

C语言-指针函数与函数指针及回调函数的使用 本章章节概述1、指针函数2、函数指针3、指针函数和函数指针的核心区别4、回调函数C语言指针进阶指针函数与函数指针指针是C语言中最强大但也最容易混淆的特性之一。我在前面章节已经讲解了指针的基础用法数组指针与指针数组的区别今天我们来深入辨析另一组极易混淆的概念-指针函数和函数指针并讲解基于函数指针实现的回调函数使用方法。这两个概念名字只有语序不同但本质天差地别是C语言进阶的核心难点之一。一、指针函数指针函数从名字拆解“指针” 是修饰词核心主体是 “函数”。也就是说指针函数本质上是一个函数只不过它的返回值类型是一个指针内存地址。示例int *pfun(int a, int b);概念返回值为指针的函数叫做指针函数。作用用于在函数中返回内存地址将堆内存、静态变量或全局变量的地址返回给调用者实现跨函数的内存操作与数据传递。注意指针函数绝对不能返回局部变量的地址因为局部变量在函数执行结束后会被系统自动回收返回的地址会变成悬空指针访问它属于未定义行为会导致程序崩溃。代码使用示例#include stdio.h int *find_max(int arr[], int len); //指针函数声明返回int类型的指针 int main() //主函数 { int num[]{1,2,3,4,5,66,7,8,9,10}; int len_long sizeof(num) / sizeof(int); int *max find_max(num, len_long); printf(数组中最大的值为 %d\n, *max); printf(最大值所在的内存地址为:%p\n, max); return 0; } int *find_max(int arr[], int len) //指针函数:返回值指针,形参数组和变量,功能数组中找最大值 { int *max_p arr[0]; for(int i 1; i len; i) { if(arr[i] *max_p) { max_p arr[i]; //更新获取最大值的地址 } } return max_p; } [Running] cd c:\Users\LiYongFeng\Desktop\Test-C\ gcc test1.c -o test1 c:\Users\LiYongFeng\Desktop\Test-C\test1 数组中最大的值为 66 最大值所在的内存地址为:0061FF04 [Done] exited with code0 in 1.291 seconds核心要点指针函数的核心是函数它的特殊之处只在于返回值是指针而非常量数值。二、函数指针函数指针从名字拆解“函数” 是修饰词核心主体是 “指针”。也就是说函数指针本质上是一个指针变量只不过它指向的不是普通变量而是一个函数的入口地址。示例本质是指针指向函数入口地址的指针叫做函数指针。int (*fptr)(int, int);注意只有返回值类型、参数个数、参数类型、参数顺序完全一致的函数才能被同一个函数指针指向。作用利用函数指针可以实现动态调用函数、将函数作为参数传递是实现回调机制、多态逻辑的基础。代码使用示例#include stdio.h int add(int a, int b); // 函数声明 int sub(int a, int b); // 函数声明 int main() { int (*p_func)(int, int); // 函数指针声明 int i10, j20; p_func add; printf(%d %d %d\n, i, j, p_func(i, j)); p_func sub; printf(%d - %d %d\n,i,j, p_func(i, j)); return 0; } int add(int a, int b) { return a b; } int sub(int a, int b) { return a - b; } [Running] cd c:\Users\LiYongFeng\Desktop\Test-C\ gcc test1.c -o test1 c:\Users\LiYongFeng\Desktop\Test-C\test1 10 20 30 10 - 20 -10 [Done] exited with code0 in 0.364 seconds三、指针函数和函数指针的核心区别很多人分不清这两个概念核心就是搞不清「谁是主体」。我们从本质、语法、用途三个维度彻底区分开。1. 本质不同指针函数本质是函数和普通函数地位一样只是返回值是指针。函数指针本质是指针变量和普通指针地位一样只是指向的是函数地址。2. 声明语法不同最直观区分标志关键看*和函数名有没有被括号括起来注意括号是灵魂*和变量名被括号包起来的就是函数指针没有括号的就是指针函数。概念声明示例结合规则指针函数int *func(int);()优先级高于*func 先和 () 结合说明是函数返回值类型是 int*函数指针int (*p)(int);括号改变优先级p 先和 * 结合说明是指针指针指向 int (int) 类型的函数3. 用途不同指针函数用于返回内存地址比如返回动态分配的内存首地址、返回数组中的元素地址等。函数指针用于动态调用函数、作为函数参数传递、实现回调机制、状态机、函数跳转表等。四、回调函数的使用回调函数是 C 语言中非常重要的编程机制它的底层实现完全依赖于函数指针。概念如果把一个函数的指针地址作为参数传递给另一个函数当这个指针被用来调用它所指向的函数时我们就称这个被调用的函数为回调函数Callback Function。简单理解回调函数不是由该函数的实现方自己直接调用而是由另外一个 “框架函数” 在特定时机或条件下通过传进来的函数指针间接调用。作用解耦通用逻辑和具体业务分离框架不用关心底层具体实现。灵活扩展可以在不修改框架函数的前提下新增不同的处理逻辑。异步通知常用于事件触发、中断处理、定时任务等场景。回调函数的使用步骤约定回调函数的参数和返回值格式实现符合格式的回调函数可以有多个定义框架函数接收函数指针作为参数调用框架函数时将回调函数的地址传入。#include stdio.h void print_app1(int num); //打印形参函数1 void print_app2(int num); //打印形参函数2 void array_traversal(int arr[], int len, void (*func)(int)); int main() { int arr[] {1, 2, 3, 4, 5}; int len sizeof(arr) / sizeof(int); printf(原数组为:\n); array_traversal(arr, 5, print_app1); printf(乘二后的数组为:\n); array_traversal(arr, 5, print_app2); return 0; } void print_app1(int num) //打印形参函数 { printf(app1: %d\n, num); } void print_app2(int num) //打印形参*2函数 { printf(app2: %d\n, num*2); } //框架函数 通用数组遍历 //第三个形参就是完整的函数指针类型void (*func)(int) void array_traversal(int arr[], int len, void (*func)(int)) { for(int i 0; i len; i) { func(arr[i]); //通过函数指针调用回调函数处理当前元素 } printf(\n); }制作不易喜欢的小伙伴给个小赞赞喜欢我的小伙伴点个关注有不懂的地方和需要的资源随时问我哟
返回列表