发现一道很有意思的题,跟大家分享一下--C指针

1.原题
看到这样的一道题,和大家分享一下,判断下列代码输出的内容,代码如下:

#include<stdio.h>
#include<stdlib.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);  
system("pause")
return 0;
}

2.过程
这题考的是C语言中的指针的应用,我们可以把它的内存图画出来
在这里插入图片描述
请注意下标的地址,这四个字符串在内存中的存储位置是随机的,并不一定会连起来。
加下来画出 char* c[ ],由于char* 是一个一级指针,所以c[ ]中存储的就是这四个字符串的地址,假设从 c [ ] 的首地址为 0x2000
在这里插入图片描述
接下来是 char** cp [ ],这个中的地址是按照代码中的 c + 3 ,c + 2 , c + 1 , c的顺序排列的
在这里插入图片描述
下来是 char*** cpp , 这个根据代码中的内容,这个三级指针中存放的是二级指针的首元素的地址,所以有
在这里插入图片描述
下来开始解答代码

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

这条代码中存在一个优先级的问题,一般在没有括号的情况下是从右往左看的,所以我们首先要看的是 ++cpp 。由上面的分析得到, cpp 现在里面存放的是 二级指针 cp 的地址,所以 ++cpp 也就是给 0x3000 地址 +4 ,因为指针在 32 位的系统中统一占 4 个字节,所以 ++cpp 后 ,就变成了 0x3004 ,在进行解引用,所以这一条代码打印出来的是 " POINT"

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

这条代码与上一条差不多,只不过出现了后面的 + 3 ,按照优先级原则,先从 ++cpp 看起,由于 cpp 中的内容已经变成 0x3004,所以这里再 ++ 的话,就会变成 0x3008 ,解引用一次,对应得到的是 0x3008中对应的内容,也就是 0x2004,再 – ,就得到了 0x2000,再解引用,就得到了 字符串" ENTER " ,后面的 +3 是在 “ENTER”的首地址上加 3 ,也就是指针往后走三个字节,从第四个字节开始打印,一直到遇到 \0 停止,所以这条代码打印出来的内容应该是 “ER”

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

这条代码显示对 cpp 进行中的内容进行 -2 操作,这里的 *cpp[-2] 也可以表示成 *(cpp - 2),请注意,这里的 - 2 操作并不会改变 cpp 中的值,cpp -2 得到的是 0x3000,解引用后得到 0x200c,其中的内容是 0x400,再 + 3 表示将 0x400中的内容往后移三个字节再打印,所以打印出来的就是 “ST”

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值