(一)基本知识
1、&函数名
根据以前学到的知识,我们知道 & 是取出地址,如:
int a = 0 ;
int arr = { 0 } ;
&a;//取出a的地址
&arr;//取出数组的地址
真相只有一个!!!
&函数名就是函数地址
注:函数名==&函数名(和数组略微不同)
2、指针和函数
先来一段代码(使用函数实现两个数的相加)
#include<stdio.h> int add(int x, int y)//定义一个函数实现整数的相加 { return x + y; } int main() { int a, b; scanf_s("%d %d", &a, &b); int c = add(a, b);//常规调用 printf("%d\n", c); return 0; }
(1)我们之前学过如何调用函数,即直接使用函数名称。
(2)现在我们已经知道了函数名就是函数的地址,那么我们可以定义一个指针变量来指向函数,然后使用该变量间接使用函数吗?
先看代码:
#include<stdio.h> int add(int x, int y)//定义一个函数实现整数的相加 { return x + y; } int main() { int a, b; scanf_s("%d %d", &a, &b); int(*pf)(int, int) = &add;//函数指针 int d = (*pf)(a, b);//调用 printf("%d\n", d); return 0; }
(1)上述代码函数指针是怎么写出来的?
1.先来看变量名称 :*pf //显而易见这是一个指针
2.再看外层:int()(int , int)//这不就是缺漏函数名称的一个函数嘛
3.所以这就是函数指针的写法
3、调用
上述代码中出现了
int d = (*pf)(a, b); //调用
这就是使用指针变量来调用函数的方式
除此之外还可以写为:int d = pf( a , b);
可以认为:*pf == add == pf
易错点:写为 int d = *pf (a , b);
(二)练习
1.共同练习
(*(void(*)( ) )0 )( ) ; //看看这个代码,你认为是什么呢?
某人:!!!are you?! ! !
别慌,让我们来慢慢分析
(1)首先此代码中出现了 0 ,0是一个整数,放在这里合适吗?有人说这没有意义啊,没有(void(*)( ) )这些,不就是解引用嘛,多简单啊
来,看看代码这样写合适吗?
程序报错,并且给出提示, * 的操作数必须是指针,但此时的 0 是int 类型,那么你想到了什么?
真相只有一个,那就是0之前的(void(*)( ) )就是对0进行了强制类型转换,从而使其成为函数指针类型,那又有个疑问,为什么是函数指针类型呢?
原因就在于去掉()剩余的 void(*)( ) 这不就是一个函数指针但是没有具体的变量名称嘛,所以为函数指针类型
综上:
(1)0被(void(*)( ) )强制类型转换为函数指针类型
(2)外层是对其进行解引用,(*)( )
(3)函数作用是用来调用0地址处的函数
(注:此代码实在某种特殊的情况下,一般来说0地址处是不能使用的)
2.自我练习:
void(* signal(int , void(* )(int)))(int);//这串代码的含义是什么?