1. 二级指针
定义:指向一级指针变量的指针;
int *p;
char *p;
double *p;
int **p;
2. void *指针:
void *p; ----所有指针都是8字节;
void *指针仅用来保存地址;
void * -> int */ char */ double * 不需要强制类型转换;
int */ char */ double * -> void * 需要强制转换(因为会舍弃精度,低精度 -> 高精度);
void * 作为函数参数,可以传入char *、double *、 int * 的指针,实现一个函数原型下的不同类型指针的传参;
3. const指针:
const == readonly 只读
操作指针有如下几种形式:
1. const int *p;
2. int const *p;(与1等价,表示const修饰 *p ,*p 不可改变,而 p 可以改变,不能用 p 修改它指向空间中的值) 只能使用指针指向空间的数据,不能修改此数据;
3. int *const p;(const修饰 p ,p不可变,但 *p 可以改变,一定要初始化,否则该指针后续无法指向其余空间,永远为野指针)
int const *p = NULL; 永远指向某个空间的指针(比如数组的数组名)
4. const int *const p;
5. int const *const p;(与4等价,const同时修饰 p 和 *p ,二者均无法改变,一定要初始化)
4. 数组指针和指针数组:
1. 数组指针:
数组指针是指针,指针指向的是整个数组;
对一维数组的数组名取 &(值不变,类型升级),得到指向整个数组的数组指针;
对数组指针取 *,值不变,类型降级成为指向第一个元素的指针;
int a[5] = {1, 2, 3, 4, 5};
a可以理解为int *
注意:以下两种情况不能理解为int *型;
1. sizeof操作;
2. &操作;
&int * == int **
&a == int (*)[5]
对数组的数组名取地址会得到一个指向整个数组的指针;
2. 指针数组
指针数组是数组,数组的每个元素都是指针;
int *a[5] :定义了一个数组名为a,有五个元素,每个元素为int *型,占40个字节空间;
char *pstr[5] : 每个元素都是一个char*型的指针;
存放字符串数组用二维数组,操作字符串数组用指针数组;