牛客网刷题笔记之指针题(超详细解答过程)

请写出下列程序的输出结果:

#include<stdio.h>

char *c[] = { "ENTER", "NEW", "POINT", "FIRST" }; 
char **cp[] = { c+3, c+2, c+1, c }; 
char ***cpp = cp; 

int main(void)
{ 
    printf("%s\n", **++cpp);
    printf("%s\n", *--*++cpp+3);
    printf("%s\n", *cpp[-2]+3);
    printf("%s\n", cpp[-1][-1]+1);
    return 0;
}

做这道题之前,我们先明确几个概念:

1、p++,p--,++p,--p会影响指针的指向。

例如: 

  ++p相当于p = p + 1;     指针会保存改变后的指向。

2、p+2;这样表达式运算完后,指针指向不会受到影响,因为它并未保存改变后的指向。

3、数组与指针之间的转换:

例如:

  p[2] = *(p+2);p为数组首地址,p相当于&p[0],p+2相当于&(p+2),最左边加*,表示取值,即p[2]。

  p[-1][-1] = *(*(p-1)-1);同理

分析:
① 对于 **++cpp来说,一开始cpp指向cp,即指向存放c+3的地址,

然后表达式先执行++cpp,指针后移,且保存指向,即指向存放c+2的地址,

之后*++cpp,解一层引用,指向地址中的内容c+2,即指向*c[]中存放第三个字符串的地址,

再执行**++cpp,即指向这个字符串的第一个的元素P,

然后输出,从P开始输出,遇到'\0'结束,即输出 POINT

 

② 对于*--*++cpp+3来说,现在cpp已经指向存放c+2的地址了,

先执行++cpp,即cpp指向存放c+1的地址,

然后执行*++cpp,即cpp指向*c[]中存放第二个字符串的地址,

再执行--*++cpp,即cpp指向*c[]中存放第一个字符串的地址,

再执行*--*++cpp,即cpp指向第一个字符串的第一个字符E,

再执行*--*++cpp+3,即cpp指向第一个字符串的第四个字符E,

再输出,结果为ER

 

③ 对于*cpp[-2]+3,目前cpp指向存放c+1的地址,

将表达式化简一下,即**(cpp-2)+3,

先执行cpp-2,cpp指向存放c+3的地址,

然后执行*(cpp-2),cpp指向*c[]中存放第四个字符串的地址,

再执行**(cpp-2),cpp指向第四个字符串的第一个字符F,

再执行**(cpp-2)+3,cpp指向第四个字符串的第四个字符S,

再输出,结果为ST

 

④ 对于cpp[-1][-1]+1,现在cpp还是指向存放c+1的地址,

将表达式化简一下,即*(*(cpp-1)-1)+1,

先执行cpp-1,cpp执行存放c+2的地址,

然后执行*(cpp-1),cpp指向*c[]中存放第三个字符串的地址,

再执行*(cpp-1)-1,cpp指向*c[]中存放第二个字符串的地址,

再执行*(*(cpp-1)-1),cpp指向第二个字符串的第一个字符N,

再执行*(*(cpp-1)-1)+1,cpp指向第二个字符串的第二个字符E,

输出,结果为EW

 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值