根据下述代码,我们就能好好整理上char *c[], **cp[],char ***cpp的关系。
首先char *c[]是一个指针数组,重点在于它是一个数组,存放的都是指针,而且每个指针都指向一个字符串。
char **cp[]是一个二级指针数组,它里面的指针指向数组char *c[]
char ***cpp 是一个三级指针,指向二级指针数组char **cp[]。
它们的关系图。
首先要正确分析出问题,最重要的是要掌握两个技能:1、运算优先级的问题 2、自加自增后会影响下一段代码的运算。
分析 printf("%s\n", **++cpp);
第一步,由于优先级的问题,先会运算++cpp,再运算**。所以原本它是指向0x00EFFD38,++后就指向了0x00EFFD3C。
第二步,再通过*解引用,它指向0x00EFFD58。
第三步,再通过*解引用,它指向PIONT的地址。
分析:printf("%s\n", *--*++cpp+3);
第一步,由于第一步中有自加,所以改变了cpp的指向,所以cpp现在指向是0x0x00EFFD3C,同时还是要注意优先级的问题,先会运算++cpp,再运算**。所以原本它是指向0x00EFFD3C,++后就指向了0x00EFFD40。
第二步,再通过*解引用,它指向0x00EFFD54,但它还有一个- -,所以地址0x00EFFD54-1变成了0x00EFFD50,因此,它把0x00EFFD40的指向变成了指向0x00EFFD50(这里改变了指针的指向,坑点)。
第三步,再通过*解引用,它指向ENTER的地址。
第四步+3,就是再在ENTER的地址+3(ENTER的地址即是E的地址),所以+3后就是E的地址,因此打印的字符串是ER。
分析为什么结果都是ENTER
printf("%s\n", cpp[1][0]);
printf("%s\n", cpp[0][0]);
分析printf("%s\n", *--*++cpp+3);的时候,我们就分析过指针0x00EFFD40的指向改变了,变成指向了0x00EFFD50,所以cpp[1][0]和cpp[0][0]都指向0x00EFFD50,即指向字符串ENTER。
分析
printf("%s\n", cpp[-1][0]);
printf("%s\n", cpp[-2][0]);
唯一注意的是cpp[0]指向的是0x00EFFD40,所以cpp[-1]指的是0x00EFFD3C,cpp[-2]指的是0x00EFFD38,所以结果是PIONT、FIRST
分析
printf("%c\n", *cpp[-1][0]);
printf("%c\n", *cpp[-1][1]);
第一步注意优先级问题,[]的优先级高于*,所以先是cpp[-1][0] =POINT cpp[-1][1]=FIRST,
第二步,再通过*解析,所以就是对字符串地址取*,所以是P和F。
如果要取P后面字母则这要写。
printf("%c\n", *(cpp[-2][0]+1));
这要就取到了P后面的I。