目录

  • 一、概述
  • 二、函数指针
    • 2.1 函数指针的使用
    • 2.2 * (int * )&p
  • 三、回调函数

一、概述

学习RTT时,看到设置和删除空闲钩子函数接口:

rt_err_t rt_thread_idle_sethook(void (*hook)(void));
rt_err_t rt_thread_idle_delhook(void (*hook)(void));

接口传入参数void (*hook)(void)该怎么理解呢?
乍一看void (*hook)(void)很像一个函数:返回值+函数名+(参数)。但是细看中间部分(*hook),又有点不对劲呀,函数名称可没有这么写的!

二、函数指针

如果没有小括号:void *hook(void),这个很肯定就是一个函数。增加小括号以后,优先级改变,(*hook)使得*hook组合,成为一个指针。
所以void (*hook)(void)表示:hook是一个指针,指向一个函数。这个函数参数为void,返回值也是void。

2.1 函数指针的使用

既然明确了是一个指针,那么就可以当成一个普通指针来使用。以前使用一个整形指针如下:

    int *p = NULL;int i = 10;p = &i;

现在函数指针也是如此:

    void (*pf)(void) = NULL;pf = &fun;(*pf) ();

看下运行结果:

2.2 * (int * )&p

在上面赋值函数指针时,使用了pf = &fun;,还可以使用另一种方式:

 void (*pf)(void) = NULL;...//pf = &fun;*(int*)&pf=(int)fun;(*pf) ();

先看下运行结果:


那么*(int*)&pf=(int)fun;该怎么理解呢?先看等式的左值,可以分为三层:

  1. &pf,显然这是取地址。pf是我们定义的函数指针,&pf 也就是求指针变量 pf 本身的地址。
  2. (int*),这是进行强制转换。(int*)&pf 表示将地址强制转换成指向 int 类型数据的指针。
  3. 最外层的* ,也就是按照地址进行取值。在2.1节printf("p point value = %d\r\n", *p);,就是这样的形式啊。

再看等式的右值。fun是函数名,也就是函数地址。(int)fun 表示将函数的入口地址强制转换成 int 类型的数据。

所以*(int*)&pf = (int)fun;表示将函数的入口地址赋值给指针变量 pf。

那么为什么要使用函数指针呢?

你不会每天都是用函数指针。但是,它们确有用武之地,最常见的两个用途是转换表(jump table)和作为参数传递给另一个函数。《C和指针》

三、回调函数

可以看出,在RTT设置删除空闲钩子函数中,正是第二种情况:作为参数传递给另一个函数。

使用这种技巧的函数被称为回调函数(callback
function),因为用户把一个函数指针作为参数传递给其他函数,后者将“回调”用户的函数。《C和指针》

回调函数有什么好处呢?我的理解是,便于分层,使得程序架构更清晰,降低耦合。
尤其是在多人共同完成时,有人做驱动,有人做逻辑应用。做驱动无需关系中断内需要做什么,预留出接口即可。做应用也不必关心中断内如何调用,只需要实现回调函数,注册一下就行了。这样既能同步进行开发,也使得程序更加清晰。

追踪了下RTT的设置空闲函数:

void rt_thread_idle_sethook(void (*hook)(void))
{rt_thread_idle_hook = hook;
}static void rt_thread_idle_entry(void *parameter)
{while (1){#ifdef RT_USING_IDLE_HOOKif (rt_thread_idle_hook != RT_NULL){rt_thread_idle_hook();}
#endifrt_thread_idle_excute();}
}

RTT启动函数rtthread_startup中初始化了空闲线程,而线程函数中通过函数指针,最终调用了void (*hook)(void)指向的用户函数(如果开启了宏定义)。
这也就是前面说的,我们不必关心空闲线程具体怎么初始化,线程函数具体如何实现。只需要把我们想在空闲线程内做的事情封装成函数,通过函数指针传进去就行了。

RTT设置删除空闲钩子函数想到函数指针和回调函数相关推荐

  1. c语言注册回调函数主要用途,C语言回调函数的概念及其应用

    笔者能力有限,如果文中有错误的地方,欢迎各位朋友给我及时地指出来,我将不甚感激,谢谢~ 概念 引用维基百科上的关于回调函数的概念:在计算机程序设计中,回调函数,或简称回调(Callback 即call ...

  2. c语言键盘回调函数键盘的码,深入浅出剖析C语言函数指针与回调函数(三)

    前面两篇文章: http://blog.csdn.net/morixinguan/article/details/65494239 http://blog.csdn.net/morixinguan/a ...

  3. php回调函数的作用域,PHP将回调函数作用到给定数组单元的方法

    PHP将回调函数作用到给定数组单元的方法 数组是PHP程序设计中十分重要的一环.本文介绍PHP中数组函数array_map()的用法,实现将回调函数作用到给定数组单元上.具体如下: array arr ...

  4. 函数指针与回调函数详解

    函数指针与回调函数详解 1.什么是函数指针? 函数(的)指针就是指针.这个指针存放一个函数的地址,而函数的名称就该函数的入口,即地址.这类似于数组名就是数组的首地址.我们可以通过反汇编直观的查看到函数 ...

  5. 网络编程之 信号捕捉器(函数指针与回调函数)

    接着我们的信号说下去      之前博主给大家分享到了信号的概念和初步介绍signal函数的形式后就没有继续往下介绍了,实在是因为时间不够,那个时候博主还要上课,现在博主放假了就好好给大家分享一下如何 ...

  6. c语言函数指针封装函数,C语言之函数指针、回调函数的使用

    一.背景 首先看下如下代码,这个定义是放在头文件的,在程序中tCdrvCallbackFkt也定义了另一个变量,而且括号后面还跟定义了几个变量,不理解这个定义. typedef void (PUBLI ...

  7. c语言 函数指针 菜鸟教程,C 函数指针与回调函数 | 菜鸟教程

    函数指针 函数指针是指向函数的指针变量. 通常我们说的指针变量是指向一个整型.字符型或数组等变量,而函数指针是指向函数. 函数指针可以像一般函数一样,用于调用函数.传递参数. 函数指针变量的声明: t ...

  8. 回调函数 —— 借助中间通用函数(形参里有函数指针,实现函数注册)调用不同的回调函数 (多态/分层)

    回调函数传参:函数指针做函数参数(回调函数) 目录 背景 回调函数是实现函数分层且单向依赖的好办法,使用函数指针运行 struct结构体回调函数代码更清晰 简单理解回调函数 Demo 其他回调函数博文 ...

  9. 【C语言进阶深度学习记录】三十二 函数指针与使用函数指针实现回调函数

    回调函数是非常重要的概念 文章目录 1 函数的类型 2 函数指针 2.1 函数指针的使用 2.2 使用函数指针实现回调函数 3 总结 1 函数的类型 跟以前学数组的时候是一样的,C语言中的数组是有自己 ...

最新文章

  1. 《Python Cookbook 3rd》笔记(3.12):基本的日期与时间转换
  2. 【Java】单循环链表解决约瑟夫环问题
  3. GeeksForGeeks 翻译计划 | ApacheCN
  4. Flink – WindowedStream
  5. mysql查binlog删除时间_mysql的binlog日志删除查询
  6. React全家桶构建一款Web音乐App实战(五):歌曲状态管理及播放功能实现
  7. mysql判断是日期是第几周
  8. window.location.href的使用方法
  9. 1、MyBatis下载地址以及简介
  10. 信号与系统学习笔记与代码实现3-周期信号的傅里叶级数表示
  11. find 命令多条件匹配
  12. 流媒体 直播细节优化
  13. Intel Core系列CPU架构演变
  14. docker tomcat 多开 实例_Docker快速验证tomcat单机多实例方案
  15. 政务区块链平台设计思路
  16. Java中beimage_GitHub - beconf/ImageBlurring: Android 中通过 Java 与 JNI 分别进行图片模糊;并且进行比较其运算速度。...
  17. 【软件测试】—— 水杯测试用例
  18. StringUtils 工具
  19. logback中logger的 additivity 属性
  20. 最全的中国大陆运营商所有号段!

热门文章

  1. viper4android最新,ViPER4Android FX音效驱动下载-ViPER4Android音效驱动 v2.4.0.1 正式版_手机乐园...
  2. java实现系统参数的存储_基于ZooKeeper,Spring设计实现的参数系统
  3. python3 opencv_python3 opencv3 实现基本的人脸检测、识别功能
  4. 写python的笔记本_python笔记本:更改写入的fi
  5. redis desktop manager 集群_Redis Manager(2.0) —— Redis 运维利器
  6. 计算机组装的虚拟仿真实验报告,组装计算机的虚拟实验室
  7. linux 调整shmmax,科学网—Ubuntu 9.10 中更改 linux kernal 中的shmmax大小 - 孙鹏的博文...
  8. DSP芯片概述--7.24
  9. Linux系统中文件的访问权限
  10. 设备独立的操作系统软件