一、结构体数组
该数组的每个元素都是一个结构体,结构体数组格式:声明变量类型 数组名称[数组长度]
二、函数指针
函数指针本质是一个指针,指针指向d 地址是一个函数,所以它是指向函数的指针
C语言中,函数的定义是存放于代码段,每个函数在代码段中有入口地址,函数指针就是指向代码段中某函数入口地址的指针
声明形式:ret (*p)(args, *argv);
备注:
- 函数指针不可以用来做加减运算
- (*指针变量名) 形式的两边的括号不可少,其中的 * 是一种表示符号,不是求值运算
2.1 函数指针的初始化
函数指针是需要把一个函数的地址赋值给它,函数名即是该函数的入口地址,因此,函数名就是该函数的函数指针,因此函数指针的初始化可以这么写:函数指针变量 = 函数名;
2.2 函数指针的应用:回调函数
回调函数就是一个通过指针函数调用的函数,回调函数将函数指针作为一个参数,传递给另一个函数
回调函数并不是由函数设计者调用,而是在特定的事件或条件发生时由另外一方来调用
三、指针函数
指针函数本质是一个函数,不过它的返回值是一个指针
声明的形式:ret *func(args, *argv);
其中,* 可以靠近ret,也可以靠近func,也可以在二者中间,一般选择靠近ret,这样看上去更像一个指针
备注:
在使用指针函数的时候,一定要避免出现返回局部变量指针的情况,因为局部变量是存放于栈区,当函数结束,栈区的变量就会释放掉,如果在函数内部定义一个变量,然后使用一个指针去指向这个变量,当函数调用结束时,这个变量的空间就已经被释放,如果函数返回值是返回了该地址的指针,那么程序 不一定 会得到正确的值
四、函数指针变量
函数指针变量调用步骤:
- 先定义函数指针变量,定义为函数指针变量
- 把被调函数的入口地址(函数名)赋予该函数指针变量
- 用函数指针变量形式调用函数,调用形式为: (*指针变量名) (实参表)
五、函数指针数组
函数指针数组就是存放多个函数指针的数组,函数指针数组可以有效降低圈复杂度
例如:int (*p1)[32](int, int);
备注:
- 函数的返回类型一样,并且函数的形参也是要一样
- 在swith函数中使用函数指针数组,可以简化代码
六、数组指针
数组指针:本质是指针,是指向数组的指针
形式:(*p)[n]
例如:
#include "stdio.h"
int main()
{
int a[5] = {
1, 2, 3, 4, 5 }; // a 数组里有 5 个元素
int (*p)[5]; //定义一个数组指针 p
p = &a; //把数组a的地址赋给p,故 p 为数组 a 的地址,*p 表示数组 a 本身
printf("%p\n", a); //打印数组名
printf("%p\n", p); //打印数组 a 的地址
printf("%p\n", *p); //打印数组的首元素地址
printf("%p\n", &a[0]); //打印a[0]的地址
printf("%p\n", &a[1]); //打印a[1]的地址
printf("%p\n", p[0]); //打印数组首元素的地址
printf("%d\n", **p); //打印首元素的值
printf("%d\n", *p[0]); //打印首元素的值
return 0;
}
七、指针数组
指针数组:本质是数组,数组元素是指针
形式:*p[n]
例如:
#include "stdio.h"
int main()
{
int a = 1;
int b = 2;
int *p[2];
p[0] = &a;
p[1] = &b;
printf("%p\n", p[0]); //打印a的地址
printf("%p\n", &a); //打印a的地址
printf("%p\n", p[1]); //打印b的地址
printf("%p\n", &b); //打印b的地址
printf("%d\n", *p[0]); //p[0]表示a的地址,*p[0]表示打印a的值
printf("%d\n", *p[1]); //p[1]表示b的地址,*p[1]表示打印b的值
return 0;
}
备注:
- 数组指针是一个指针变量,占有内存中一个指针的存储空间,在32位系统中,指针占四个字节
- 指针数组是多个指针变量,以数组的形式存储在内存中,占有多个指针的存储空间