1、指针数组:
指针数组是一个包含指针元素的数组。每个数组元素都是一个指针,它可以指向不同的数据类型或者相同的数据类型。(本质是数组,每个元素为指针类型)。
(1)、指针数组的用法
1、字符指针数组 存放多个字符串数组,方便管理。
char *str[] = {"aaaa","bbbbb"}; char buf[][20] = {"cccc","dddd"};
char *str[2] = buf 错误的赋值,指针数组也是数组,是一个符号常量不能改变。
char(*str)[2] = buf 正确的赋值,数组指针本质变量,可以改变。
(2)、字符指针数组和二维字符数组的区别
字符指针数组:本质是数组,每个元素存放字符串的首地址。
二位字符数组:本质是数组,用数组的空间存放字符串。
2、数组指针:
本身是一个指针,指针指向数组的地址,指针加1相当于跳过当前数组,指向下一个数组。
(1)、用数组指针来遍历二维数组
(2)、指针数组和数组指针的区别
指针数组: int *p[5] 本质是数组,里面存放的是指针,常用来存放多个字符串,方便管理。
数组指针: int (*p)p[5]本质是指针变量,指针指向数组的地址(不是元素的地址),一般用来指向二维数组。
(3)、数组指针和多为数组的联系
二维数组 一维指针数组 | int arr[3][4] | int (*p)[4] |
三维数组 二维指针数组 | int arr[3][4][5] | int (*p)[4][5] |
四维数组 三维指针数组 | int arr[3][4][5][6] | int (*p)[4][5][6] |
N维数组以此类推,在逻辑上多维数组,但是在物理上都是一维的。
3、指针和函数的关系
(1)、通过函数名直接调用函数
(2)、通过函数的地址来调用
(3)、指针变量作为函数的参数
(3.1)、函数单向传递-值传递
变量名作为函数的形参传递,主函数内部无法修改实参的值。
最后输出的结果和自定义函数没有关系的原因在于:test01里面的num复制在栈区,当前函数test01结束后会失去作用范围。
(3.2)、函数单向传递-地址传递
地址传递相当于指针指向num的地址,而不是复制到栈区,所以可以通过修改原本的num的值来传递。
(3)、字符数组作为函数的参数
:数组名作为形参,函数内部就可以操作数组元素的内容。(在函数中形参为数组时一律当作指针对待)。
(4)、一维数值数组作为函数的形参
一维数值数组作为参数,应该用一级指针来接收。
(5)、数组指针作为函数的形参
数组指针作为形参一般是用于二维数组的传递
(6)、二级指针作为函数的形参
(7)、求最大值最小值
(8)、指针作为函数的返回值
指针作为函数的返回值,在retrun的时候需要传递地址(str),在接收的时候需要用指针去接收。
4、函数指针变量
函数指针变量的定义方式 void (*p)() = NULL 或者 typedef int(*p)(int int)重命名
(1)、保存函数入口地址
写法1:
写法2:
(2)、实例根据标准端输入的add/sub/mul/div调用不同的函数
(2)、函数指针变量的注意事项
1、不要对函数指针变量取*无意义会被编译器优化。
2、函数指针变量+1 -1没有意义。
3、函数指针变量> < >= <=没有意义。
4、函数指针变量 = == != 有意义。
5、函数指针应用场景
优点:让函数功能多样化,作为回调函数可以隐藏底层逻辑。
(1)main 函数传参
(2)、指针的拓展
1、const int *p:指针常量,指针指向的是常量。
2、int const *p:指针常量。
3、int *const p:常量指针,指针是常量。
4、const int *const p:常量指针常量,指针常量指向的也是常量。