函数指针的实质是一个指针变量,这个变量本身占4个字节(在32位系统中)
函数的实质是一段代码,这段代码在内存中是一段连续分布的内存空间。对于函数中最关键的函数第一个地址(找到函数第一地址就能找到整个函数代码),这个函数首地址在C语言中就由函数名来表示。
指针(函数指针,数组指针,普通指针)的实质都是指向一段内存空间,内存空间中存储的内容各自不同(对于函数指针就是一段代码;对于数组指针就是数组;对于普通变量就是变量内存空间)
再解释下函数指针这个含义: 函数指针其实就是一个普通变量,这个普通变量的类型是函数指针变量类型,它的值就是某个函数的地址(也就是它的函数名这个符号在编译器中对应的值)
为什么C语言中会存在复杂的变量类型?
C语言本身是强类型语言(每个变量都有自己的变量类型),编译器可以帮我们做严格的类型检查错误。所有的指针变量都是一样的,但是C语言中存在不同类型的指针,这些指针指向变量/数组等(int *p、int (*p)[5] ),这些符号给编译器提供更多的信息,让编译器检查这个变量在代码中的应用,如果编译器检查到类型不匹配就会报错。
注意: 不是所有的语言都是强类型语言的,也存在弱类型的语言(Shell、Makefile等),在弱类型语言中所有的变量没有自己的变量类型。
假设有个函数为void func(void),对应的函数指针为void (*p)(void)。 ———— 函数指针定义
p = func; ————函数指针赋值
p(); ———— 函数指针调用
注意: 在C语言编译器中定义,函数名做右值的时候加不加&效果和意义都是一样的。
void (*Pfunc)(char *, const char *)
分析:核心为Pfunc ; 根据C语言中符号的优先级(()的优先级比 * 的高)。与核心最近的 * 符号先结合,表示这个Pfunc是一个指针。(*Pfunc)整体再与()结合表示这个指针指向的是函数。所以整个符号表示的是函数指针。
分析方法与步骤可参考:C语言基础篇 —— 3-1 一文秒懂指针数组与数组指针
结构体内部内嵌函数指针实现分层
复杂的程序东西太多一个人搞不定,需要更多人协同工作完成。在linux复杂的内核程序中用了很多这种分层(上层和下层)写代码的思想和方法。
上层注重的是实现业务逻辑,与我们最终的目标直接光联,并没有具体干活的函数
下层注重的是实际干活的函数,注重上层填充的变量,并将变量传递给上层中的函数来完成任务。
