1.指针的指针
指针记录着目标数据对象的首地址和类型。 那么能不能有一个指针它记录一个指针的首地址和类型呢? 我们对一个指针再次取地址,看看能不能编译通过。
#include <stdio.h>
int main()
{
int n = 123;
int *pn = &n;
printf("pn = %u\n", pn);
printf("&pn = %u\n", &pn);
return 0;
}
编译可以通过。
我们对整型n变量取地址,获取到一个int *
类型的指针。将指针存储到指针变量pn中。
之后,我们再对pn取地址。从程序运行的结果中可以看到,对pn取地址确实还可以获得一个指针。
2.指针的指针是什么类型
那么这个指针是什么类型呢?
再加一个星号就可以了。
int *
的指针的类型为int **
。
注意哦,指针变量的声明中,变量名与类型之间的空格不是那么严格。
int *p; // 正确
int*p; // 正确
int* p; // 正确
int * p;// 正确
所以这个指针的指针,我们可以写为如下几种形式:
int **p; // 正确
int**p; // 正确
int* *p; // 正确
int * *p; // 正确
int * * p; // 正确
3.多级指针
int **
是一个int *
类型数据对象的指针,所以被称之为二级指针。
和普通指针一样,它也是可以使用取值运算符*,来获取目标数据对象的。
#include <stdio.h>
int main()
{
int n = 123;
int *pn = &n;
int **pnn = &pn;
printf("**pnn = %d\n", **pnn);
return 0;
}
取地址过程:
对n使用取地址运算符,获得n的指针pn,类型为int *
。
对pn使用取地址运算符,获得pn的指针pnn,类型为int **
。
取值过程:
对pnn使用取值运算符,将int **
还原为int *
。
对*pnn使用取值运算符,将int *
还原为int
。即,还原为n。
我们将问题故意复杂化一点,你想成为五星程序员吗?
#include <stdio.h>
int main()
{
int n = 123; // int
int *oneStar = &n; // int *
int **twoStar = &oneStar; // int **
int ***threeStar = &twoStar; // int ***
int ****fourStar = &threeStar; // int ****
int *****fiveStar = &fourStar; // int *****
printf("n = %d\n", *****fiveStar); // 五次取值,还原为int
return 0;
}