只有知道具体位置,才有可能跳到那个位置去执行,如果不知道在哪里,怎么跳?
函数是什么? 函数就是一片连续的内存
数组是什么? 数组就是一片连续的内存
很显然,这一片连续的内存当中,保存的就是我们所编写的一行一行的代码
因此,我们可以推论出,真正调用函数时,跳转到这一片内存的起始位置处执行
这个位置的具体地址如何获得?
对比数组,函数名
函数和数组的本质都是连续的内存,只不过内存中的东西不一样而已,对于数组来说这一片连续的内存中存放的是一个一个的数据,对于函数来说,这一片连续的内存中存放的是一行一行的代码,本质是一样的
数组有自己独特的类型,函数也有自己独特的类型
函数类型由返回类型和参数类型所共同组成
func 函数 的类型是 Type(Type1, Type2) ,于是可进一步知道函数名所对应的类型是什么了,函数名是函数的入口地址,因此所对应的类型必然是一个指针类型,这个类型为 Type(*)(Type1,Type2)由函数类型和 * 号共同组成,因此现在可以定义指针来指向函数了,
怎么做 ?
这里的pFunc 是指针,这个指针指向 Type(Type1, Type2) 这样一个东西,这样一个东西是函数,所以知道 pFunc 指向函数,并且只能指向 Type(Type1, Type2) 这一款函数,具体指向谁?你不初始化,你不赋值,怎么知道这个指针指向谁,
所以有了这样的写法 Type (*pFunc)(Type1,Type2) = func ,
这样写就是想把 func 这一个名字所对应的函数入口地址用于初始化这个指针 *pFunc
为什么不这么写?
&func
对比前面的数组指针,肯定要加取地址符号啊,这个地方为什么直接是函数名,没有加取地址符号呐?
对一个函数来说,它的名字就是入口地址,加不加取地址符,都是一样的,数值一样,意义一样,加不加一样
add 和 mul 函数是同款,同款意味着类型相同,都是这个类型函数 int (int ,int)
pFunc 是一个指针,这个指针指向函数,指向什么类型的函数,指向 int (int ,int ) 这个类型的函数,返回值为 int ,有2 个 int 参数的函数
NULL 用 0 值来将这个指针进行初始化,因为 pFunc 再怎么复杂也是指针,既然是指针,就离不开本质,保存的就是内存地址
pFunc = add; 使得pFunc 指向 add, 指向了add ,就可以用 pFunc 来调用add 函数了,
pFunc 和 *pFunc 写法不同,意义相同
pFunc(1, 2); 直接通过函数指针进行调用,为什么,因为函数指针里面保存的就是函数的入口地址
*pFunc(1, 2); pFunc 是指针,那么这个 * 访问操作符作用于指针之后, 就意味着把这个指针所指向的东西给拿到,那么这个指针所指向的东西是什么呐?是函数,所以说就把函数拿出来进行调用
这2 种写法的效果是一模一样的,具体怎么写就看心情了
pFunc = &mul; 做了赋值操作, 使用mul 函数的地址赋值给pFunc指针,对一个函数来说,函数名就是入口地址,写不写& 都一样