C语言大神进来看看这个题目
发布日期:2021-06-30 18:42:18 浏览次数:3 分类:技术文章

本文共 1965 字,大约阅读时间需要 6 分钟。

之前一个读者给我发的一个题目,我大概看了下,题目的难度还是比较大的,而且考察的内容也比较多,可能在实际项目上使用比较少,估计十几年的老码农都没有用过,但是在看大神的代码的时候,就特别考验基本功,能不能理解理解别人的代码非常重要。

题目如下

就直接printf出几个的输出值,比较自信的大神可以直接回复答案,可以看看自己的答案对不对。

#include 
char *c[] = {"HELLO","NEW","WORLD","SAYHI"}; char **cp[]={c+3,c+2,c+1,c}; char ***cpp=cp; int main(void) { printf("%s\n",*cpp[2]); printf("%s\n",**++cpp); printf("%s\n",*--*++cpp+3); printf("%s\n",**cpp); printf("%s\n",*cpp[-2]+3); printf("%s\n",cpp[-1][-1]+1); printf("%s\n",cpp[-1]); }

图示解析

640?wx_fmt=png

解题过程

c 是一个数组,数组里面存的东西是 char *, 类型 cp 也是一个数组,数组里面存的东西是 char **, 类型 cpp 是一个指针,cpp 是一个三级指针,三级指针只能存二级指针地址

我用 gdb 调试如下640?wx_fmt=png从 gdb 调试可以看到 cpp 存的是一个地址,这个地址就是 &cp 也就是 0x601060

cp 是数组,里面的数组存的是 char ** ,如果我们想拿到 char * 的字符串,就需要使用 *p[x] 来获取里面的字符串

比如640?wx_fmt=png

几个printf 的输出结果

1、printf("%s\n",*cpp[2]);

实际上获取的就是 c+2 也就是 NEW 字符串

2、printf("%s\n",**++cpp);

** ++cpp 是先取cpp 移动到下一个位置,然后再取值,cpp移动多少位置呢?是sizeof(char ***)的大小

640?wx_fmt=png

cpp 移动 到下一个就是 c+2 所以 *++cpp 就是 "WORLD"

3、printf("%s\n",*--*++cpp+3);

这个就慢慢的显得难度上来了,看这个东西总觉得怪怪的,我们还是分解一下, 首先 ++cpp, cpp 是三级指针, 所以 *cpp 就是获取二级指针的值640?wx_fmt=png因为之前已经对 cpp做了 ++运算,所以现在cpp 指向的是 cp[1],现在又对cpp 做++运算,所以 cpp就指向了 cp[2]了,--cpp 可以理解是对指针做运算,移动的值就是 sizeof (char *** ) 。

-- * ++cpp 就是*++cpp - sizeof(char ***) 也就是 &cp[2] - 8,这个操作之后,实际上就是 &cp[3]了,前面再加上一个 ,就是cp[3]了,cp[3] +3 就是便宜3个值,也就是 "LO" 字符串了。640?wx_fmt=png

4、printf("%s\n",**cpp);

这个输出 HELLO 应该没有任何问题吧,原来题目没有这个打印的,我是为了调试而已。

5、printf("%s\n",*cpp[-2]+3);

这个也是一个超级让我们奇怪的表达式,我们可以主要看这个cpp[-2] ,cpp[-2] 可以这样理解 cpp - 2*sizeof(char ***) = cpp - 2*8 = cpp -16

我们先理一下前面的运算,现在cpp在哪个位置?

这个很关键

我们之前对cpp 进行了两次 ++ 次操作,现在cpp 应该指向 cp[2]才对,使用gdb验证试一下。

640?wx_fmt=png

那*cpp[-2] 理论上应该是 cp[0] 的值,*cpp[2] +3 的输出那应该很容易可以得出来了。就是 "HI"了。

6、printf("%s\n",cpp[-1][-1]+1);

我们知道,cpp[-1],就是当前的值往前偏移一个位置,跟上面的推断一样,当前cpp还是在cp[2]这个位置,所以cpp[-1]实际上就是cp[1]的位置,然后cpp[-1][0]就是 "WORLD"的位置,cpp[-1][-1]就是"WORLD"再往前偏移一个位置,就是"NEW"了。

后面再来一个+1 那输出结果应该就是 "EW"了

至于最后的那个print("%s\n",*cpp),因为cpp是三级指针,这样只取到二级指针,最终输出的结果应该是不确定的。

熬夜写完,也不能说完全正确,欢迎评论一起讨论,如果觉得不错,转发支持一下,如果觉得不好意思转发,点个在看让我知道有人在看,谢谢。

640?wx_fmt=jpeg

扫码或长按关注

转载地址:https://linus.blog.csdn.net/article/details/100681447 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:老师好
下一篇:如何解决Binder泄漏问题

发表评论

最新留言

逛到本站,mark一下
[***.202.152.39]2024年04月05日 12时12分56秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章