如果你觉得你指针学的自我感觉良好,甚至已经到达了炉火纯青的地步,不妨来试试这道题目?
#include<stdio.h>
int main()
{
char* c[] = { "ENTER","NEW","POINT","FIRST" };
char** cp[] = { c + 3,c + 2,c + 1,c };
char*** cpp = cp;
printf("%s\n", **++cpp);
printf("%s\n", *-- * ++cpp + 3);
printf("%s\n", *cpp[-2] + 3);
printf("%s\n", cpp[-1][-1] + 1);
}
程序的运行结果是什么? 运用自己的指针理解,不妨尝试下。
答案
解析
char**cp作为二级指针存储了一级指针c数组的内容,并且把c数组内容反向拷贝到了cp指针数组。
且三级指针***cpp存储的二级指针**cp的地址,且指向cp中指针数组中第一个元素(FIRST)。
前置++的优先级是高于解引用*的优先级的 因此我们先++cpp 再解引用++cpp的空间
cpp是指向cp指针数组元素中第一个元素(FRIST),++cpp相当于跳过char**(cp+1)字节空间 也就是一个指针变量大小4/8
在32位环境下指针变量大小是4 64位环境下指针变量大小是8
原本cpp指向cp中c+3元素(FIRST),前置++跳过char**(cp+1)字节大小,*cpp指向了cp中c+2元素(POINT),**cpp再解引用cp指针数组中c+2中元素(POINT)的全部内容,因此第一个打印POINT。
第二个一样要先考虑优先级的问题,前置++要高于前置--的优先级,+的优先级最低
但一定要记住前置++和前置--是有改变性的,第一次打印%s内容时++cpp了 因此这次cpp指向的是cp指针数组中c+3元素(POINT)的位置。
先++cpp 指向了cp指针数组中c+1的位置
再* ++cpp 获得cp指针数组中c+1元素的全部内容
然后*-- c+1-1=c 获得了cp指针数组中c位置(ENTER)的全部内容
最后在+3是E的位置,在依次打印,就输出ER
*cpp[-2]可以理解为**(cpp-2) **(cpp-2)+3 优先级+是最低的
cpp-2指向cp指针数组中c+3的位置 再解引用获得了cp指针数组中c+3元素的全部内容(FIRST)
最后+3是S的位置 因此输出ST
cpp[-1][-1]可以理解为*(*(cpp-1)-1)+1
因为前面第二次打印时,cpp指向的是cp指针数组中c+1的位置 第三次打印并没有改变cpp的指向的位置
所以写(*(cpp-1))指向cp指针中c+2的位置
(*(cpp-1)-1) cp指针数组中c+2位置-1 变成c+1位置
*(*(cpp-1)-1)再次解引用获得cp指针数组中c+1元素的全部内容NEW
*(*(cpp-1)-1)+1是E的位置,因此输出EW。