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;
}
 
          