四、数组指针
对于一个数组的地址,可以定义一个变量来存储,该变量称为数组指针变量
1> 数组指针本质上是一个指针变量,用于存储整个数组的起始地址
2> 对于数组指针而言,指针每偏移一个单位,内存就会偏移整个数组的容量的大小
3> 数组指针一般用于二维数组,二维数组的数组名,本质上是一个数组指针常量
4> 数组指针的定义格式:数据类型 (*数组指针名)[常量];
举个例子:int arr[5] = {2,8,1,6,7};
int (*arr_ptr) [5] ; //定义了一个数组指针变量,变量名为 arr_ptr
arr_ptr = &arr; //将数组指针指向某个数组
五、指针数组
1> 本质上是一个数组,只是每个数据元素都是一个指针变量
2> 定义格式:数据类型 * 数组名[数组长度];
六、指针函数
1> 指针函数本质上是一个函数,只是函数的返回值类型是一个指针类型
例如:char * strcpy();
2> 定义格式:返回值类型 * 函数名(形参列表){函数体内容}
3> 注意:返回值为指针类型的函数,返回结果是一个左值,函数调用结果可以放在等号左侧
4> 该函数返回的地址,只能是生命周期比较长的存储空间的地址
1、全局变量
2、静态局部变量
3、主调函数以地址的形式传递到被调函数中的那块内存
例如:char * strcpy();
4、使用malloc函数动态申请的堆区空间
七、函数指针
1> 函数指针本质上是一个指针,指向函数的入口地址
2> 任何函数执行,系统都会在栈区为其分配一块用于执行的运行空间,既然有内存空间,就会有起始地址
3> 函数的名字就是函数的入口地址,如果要想将函数作为另一个函数参数的话,可以使用函数指针变量接收
这就是所谓的回调函数
4> 用处:多线程创建时用到(IO进程线程)、数据库执行sql语句时用到(网络编程)、信号处理函数调用时会用到(IO进程线程)
5> 函数指针的定义格式:数据类型 (*指针名)(参数类型);
八、函数指针数组
1> 当想要存储多个函数入口地址时,需要定义多个函数指针变量来存储
2> 数组就是一次性定义多个变量的操作
3> 想要存储多个函数指针变量,就可以定义一个函数指针数组来完成,对函数的批量处理
4> 定义格式:数据类型 (* 数组名[数组长度])(形参列表)
九、二级指针与万能指针
1> 指针变量也是在内存中占相应的存储空间的,共占8字节的空间
2> 既然有地址空间,就有起始地址,该地址也是一个比较难记忆的数字,我们可以定义一个指针变量来存储
3> 存储指针变量的地址的指针变量,我们称为二级指针变量
4> 定义格式:数据类型 ** 指针名;
5> 二级指针变量的使用:
指针变量 ----> 指向的一级指针中的地址
*指针变量 -----> 一级指针变量中的值
**指针变量 ----> 一级指针变量所指向内存空间中的值
十、万能指针
1> 万能指针可以接收任何类型的变量的地址
2> 定义格式:void * 指针名;
3> 注意:万能指针变量,只能接收给定空间的起始地址,并没有数据类型的限制
4> 万能指针变量,不能直接进行取值运算,只能转变成具体的指针变量进行取值