一、指针
定义一个数组来存储指针,也就是一个数组来存储地址。
假设存储整形数组指针。
int main(){
int a=1,b=2,c=3,d=4;
int* arr[4]={&a,&b,&c,&d};
printf("%d %d %d %d",*arr[0],*arr[1],*arr[2],*arr[3]);
结果是打印
1 2 3 4
此时的arr[0]是一个指针,指向a的指针,也就是a的地址
所以需要用*来对其解引用,从而得到*arr[0]=1;这样的结果。
区别指针数组和数组指针:
指针数组,例如
int* arr[10] 数组的内容是指针,也就是由指针构成的数组叫做,指针数组
而数组指针,例如
int (*arr)[10] =&arr 等于整个数组
用数组指针就可以存储数组的地址,地址就是指针则&arr的类型与数组指针的类型是一致的。
*arr是地址数组名
(*p)[0]=*(*p)=&arr[0]
二维数组的数组名是一个一维数组的地址,也就是第一行的地址
*解引用操作
不管是数组传参还是指针传参,传的都是指针(地址),只要搞明白你要传的地址是什么类型的,然
后用对应的类型指针接收即可,就这么简单
int arr[10]={0};
int* p=arr;
arr代表arr数组的第一个地址
int* p=&arr[0];
与上式等价
而&arr表示的是整个指针地址
int*p[10]=&arr; //数组指针
二.野指针
野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址, 意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的 。
如何规避野指针
1.指针初始化
2.小心指针越界
3.指针指向空间释放即使置NULL
4.避免返回局部变量的地址
5.指针使用之前检查有效性
int arr[5]; arr是一个5元素的整形数组
int *p[10];p与[]先结合是一个数组,数组有10个元素,每个元素的类型为int *
int (*p)[10];p与*结合是一个指针,指针类型是int(*)[10],数组指针指向一个数组,数组存储10个整形的元素
int (* p[10])[5]; p先与[]结合是一个数组,去掉数组名和元素个数p[10],剩下的是数组每个元素的类型为int(*)[5],该类型是一个数组指针指向数组有5个整形的元素。
总结:p是一个数组,每个数组的元素是一个数组指针,指针指向了存储5的整形的元素的数组
int (*p)(int , int );指向函数的指针,用来存放函数的地址,可以用指针变量调用该函数
int (*arr[5])(int , int );arr先与[5]结合是一个数组,去掉数组名和元素个数arr[5],剩下的int(*)(int ,int )是数组每个元素的类型是一个函数指针,
总结:arr是一个函数指针数组,数组的每个元素是一个函数指针
int (*(*pparr)[5])(int ,int);pparr先与*结合说明是一个指针,去掉数组名pparr剩下的int (*(*)[5])(int ,int)是指针类型在去掉 * 剩下的int (*[5])(int ,int)是指向数组的类型,该数组有5个元素每个元素是一个函数指针
总结:pparr是一个指向函数指针数组的指针,指向的数组有5个元素,每个元素是一个函数指针