Hello,很有缘在这篇文章上我们相遇了,那么我就用题目巩固我们多级指针的知识,当然这里的题目是比较有点难度的,我们需要有点基础呀,如果你能轻松理解题目那说明你对指针的了解已经很有基础了呢,那废话不多说,开始进入正题了~
望喜欢
操作多级指针加减题
指针加减看似简单,但有些题目却很犀利,如下题,第一次看到它我的大脑也是很混乱呢,现在已经是已经了解通透了,现在就分享给你们了,这道题可以弄出很多知识点,需要认真剖析。
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() { char* arr1[] = {"abcdefg","ABCDEF","qwertyu","QWERTY"}; char** arr2[] = { arr1 + 3,arr1 + 2,arr1 + 1, arr1 }; char*** arr3 = arr2; printf("%s\n",**arr3+1 ); printf("%s\n",**arr2+1 ); printf("%s\n",*--*++arr3+3 ); printf("%s\n", **++arr3 + 2); printf("%s\n", arr3[-2][-1]+3); printf("%s\n", **arr3); return 0; }
我们先看一下答案吧
好,现在我们就仔细剖析,为什么计算机是这样打印的。
我们且看第一第二个打印结果的剖析:
printf("%s\n",**arr3+1 ); printf("%s\n",**arr2+1 );
我们就来解析一下
图中其实也解析了其实arr3里储存的是arr2[0]的地址,也就是你可以把arr3等价于arr2用,所以这里的第一行和第二行是一样的结果,且arr3用两个指针就能打印字符串,这里是我们先用两个“ * ”指向到字符串“QWERTY”,后面加1是最后执行的,然后指针指向字符串的第二位,所以打印结果如WERTY”。
然后到第三行打印结果的解析:
printf("%s\n",*--*++arr3+3 );
图中我已经层层解析:
我们要知道++,- -和“ * ”的优先级是比较高的,所以这里我们
先++地址指向储存arr1+2的地址即arr2[1]的地址,解引用后得到(arr1+2),再到减减(- -)变成(arr1+1),再然后解引用得到“ABCDEF”字符串,最后 +3,得到字符D的地址,打印后往后打印 “DEF”
再然后是第四行打印结果的解析 :
printf("%s\n", **++arr3 + 2);
因为前面代对arr3加1过,现在arr3是指向存储arr+2的地址,这里再次++,使得arr3此时指向
arr1+1的存储地址即arr2 [2] 的地址,两次解引用后得到字符串”ABCDEF“的字符”A“的地址,再加2,得到字符”C“的地址,然后再次打印得到的结果就是”CDEF“
再然后到第五行的打印结果的解析:
printf("%s\n", arr3[-2][-1]+3);
这里需要先了解一个知识点 arr3[-2] 其实等价于 *(arr3-2),目前我们arr3指向的是arr2[2]的地址即储存arr1+1的地址,那么 -2 后解引用后得到arr1+3的存储地址即arr2 [0]处的地址,然后后面就是相当于*((arr1+3)-1),括号中运算完后得到*(arr1+2)解引用后得到字符串”qwertyu“的首地址,再加3得到字符 ”r“的地址,打印后就是得到”rtyu“。
现在到最后一行,很简单我们只需要知道现在arr3指向的是arr2中的哪一处的地址,可能很多人就想上面已经指向arr2[0]的地址,那么现在打印“QWERTY” ,如果这么想那就是错误的想法了。
printf("%s\n", **arr3);
这里上面的-2,只是解引用时-2指向arr2[0]的地址,但本身并未改变arr3,所以此时arr3指向的还是arr1+1的存储地址,所以两次解引用后便是”ABCDEF“了。