指针进阶
1.字符指针
两种写法
写法1:char ch="w"; char* p=&ch;
写法2:char* p="qew";
(是常量字符串,不可修改!)
2.指针数组
指针数组就是,存放指针的数组。
整形数组表示元素是整型的数组,那么指针数组就是元素为指针的数组。
初始化
int arr[10]={0};
int* p[10]=&arr;
3.数组指针
数组指针就是,指向数组的指针。
整型指针表示指向整型的指针,那么数组指针就是指向数组的指针。
(1).初始化
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int (*p)[10]=&arr;
这里的p就是数组指针。注意,*p[ ]如果不加括号则由于[ ]的优先级高于 * ,p会先和[ ]结合形成数组,那么看上去就是int* p[10]
这段代码表示,p是一个存放有10个整型指针的数组,是一个指针数组,而不是数组指针。
如何观察指针指向的是什么类型的数据呢?
将*p去掉,剩下的部分连读起来,就是指针指向的数据的类型。
eg:int (*p)[10]=&arr;
将(*p)去掉后,剩余int [10],看到[ ]当然就知道指向的数据是数组啦。
(2).用法
一维数组传参
传过去的是数组首元素的地址,可以是数组名,也可以是一级指针。
二维数组传参
传过去的是二维数组的首元素地址,而二维数组的首元素为第一行,因此可以是二维数组名,&一维数组或二级指针。
传入&一维数组等价于传入二级指针。
指针就是地址,&一维数组名是二维数组的首行元素的地址,可类似于一个二级指针。
一级指针传参
传入的是指针或地址,可以是一级指针,&某个变量或某个数组,数组名。
二级指针传参
传入的可以是二级指针pp,&一级指针p,指针数组的数组名。
4.函数指针
函数指针就是,指向函数的指针。
函数名与&函数名都表示函数的地址
int add(int x,int y)
{
return x+y;
}
(1).初始化
int (*pf)(int x,int y)=add;//或&add
(2).调用
int sum=(*pf)(3,8);//等价于 int sum=add(3,8);
这里的‘ * ’可有可无。
函数指针一般是在传参的时候使用。
5.函数指针数组
指向函数的指针,存放在数组中。
写法:
int (*pf[ ])(int,int);
6.指向函数指针数组的指针
写法int (*(*pf)[ ])(int,int);
7.回调函数
是一个通过函数指针调用的函数,称为回调函数。
关于void*p
1.可以接收任意类型的地址,但不可被直接解引用,也不可直接±整数;
2.在已知地址类型的情况下,可以先强制类型转换,再进行解引用或者±整数的操作。
大多数情况下,void类型用于交换数据时,可以强制类型转换为char类型,进行一个字节一个字节的交换,从而实现数据的交换。