整理今天的学习内容
1.二维数组传参的本质
int arr[3][5]={1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
二维数组可以看作每个元素是一维数组的数组,所以,根据数组名是数组首元素的地址这个规则,⼆维数组的数组名表示的就是第⼀行的地址,是⼀维数组的地址。根据上⾯的例子,第⼀行的⼀维数组的类型就是 int [5] ,所以第⼀行的地址的类型就是数组指针类型 int(*)[5] 。那就意味着⼆维数组传参本质上也是传递了地址,传递的是第⼀行这个⼀维数组的地址,那么形参也是可以写成指针形式的
arr[i][j]==*(*(p+i)+j)
2.函数指针变量
(1)函数指针变量的概念
函数指针变量是用来存放函数地址的变量,未来通过地址能够调用函数
函数名就是函数的地址,也可以通过&函数名的方式获得函数的地址
写法:int (*pf3) (int x,int y)
▏ ▏ ▏
↓ ↓ ↓
pf3指向函数的返回类型 函数指针变量名 pf3指向函数的参数类型和个数的交代
pf3指针变量的类型:int (*)(int x,int y)
(2) 函数指针变量的使用
通过函数指针调用指针指向的函数
(3)理解并解释下面两行代码:
代码1:(*(void(*)())0)();
首先,(void(*)())是函数指针类型,整型0被强制类型转换为函数指针类型,解引用后指向储存在一串全为0的指针中的函数
代码2:void(*signal(int,void(*)(int)))(int);
首先,signal(int,void(*)(int)是一个函数,它的参数是一个整型变量和一个函数指针变量,它的返回类型是参数为一个整型的函数指针变量,为了方便理解,可以看成void(*)(int) signal(int,void(*)(int));但是这样写不符合语法
(4)typedef关键字
typedef是用来类型重命名的,可以将复杂的类型简单化
重命名unsigned int:
重命名整型指针类型:
重命名数组指针类型:(新的类型名必须在*的右边)
重命名函数指针类型:(新的类型名必须在*的右边)
如果要简化代码2,可以这么写:
3.函数指针数组
(1)函数指针数组的概念:
函数指针数组是存放函数指针的数组,写法:int(*parr1[3])()
(2)函数指针数组的使用(转移表)
计算器的一般实现:
但这段代码有些冗余,使用函数指针数组的实现:
4.回调函数
(1)回调函数的概念
回调函数是⼀个通过函数指针调⽤的函数
如果把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被用来调用其所指向的函数时,被调用的函数就是回调函数
回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发⽣时由另外的⼀方调用的,用于对该事件或条件进行响应
在计算机的实现代码中,也可以使用回调函数