C语言解题——指针解析(牛客网题目)

指针,是C语言中的一个重要概念及其特点,也是掌握C语言比较困难的部分。指针也就是内存地址,指针变量是用来存放内存地址的变量,在同一CPU构架下,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。


题目场景:

下列代码输出是()

char *a[] = {"BEIJING", "SHENZHEN", "SHANGHAI", "GUANGZHOU"};
char **pa[] = {a+3, a+2, a+1, a};
char ***ppa = pa;
int main(void) {
    printf("%s, ", **++ppa);
    printf("%s, ", *--*++ppa+3);
    printf("%s, ", *ppa[-2]+3);
    printf("%s", ppa[-1][-1]+1);
}

 


答案输出

SHANGHAI, JING, NGZHOU, HENZHEN


原因分析:

 

  • 由于 pa  本身为一个常量指针,而且其类型为 char **  ,所以 pa 是一个三级指针,依次执行输出语句,

printf("%s, ", **++ppa);

        在C语言中,++ 前缀递增递减和 * 优先级相同,从右到左;后缀递增递减比前缀优先级高,从左到右;

        所以在该语句中,程序先执行

     ++ ppa

        ppa 自增,指向改变,向后移动一位,偏移量为 char **,指向 pa[1] 。 

*++ ppa

      取出 pa[1] 的内容,pa[1] 又指向了 a[2] 的地址。

**++ ppa

         取出 a[2] 的内容,a[2] 又指向字符串 "SHANGHAI",所以输出 SHANGHAI

  • 运算符优先级:++/-- 优先级大于 + ,且 + 的结合性是从左往右

printf("%s, ", *--*++ppa+3);

 由于在C语言中,++/-- 优先级大于 +,由上面可得出

++ ppa

  在上一次操作中,函数中已经改变了 ppa 的指向为 pa[1],所以在这次操作中,其指向改变,向后继续移动一位,指向 pa [2] 。

*++ ppa

取出 pa[2] 的内容,pa[2] 又指向了 a[1] 的地址。

--*++ ppa

 当对其进行 -- 操作时,由于指向了 a[1] 的地址,从 a[1] 向前移动一个 char * 的大小,指向 a[0]

*--*++ ppa

 取出 a[0] 的内容,a[0] 又指向字符串 "BEIJING",所以输出 BEIJING 

*--*++ ppa +3

 由于其输出 BEIJING ,对其 +3 使得指针向后移动 3 位,指针指向 J,对其进行输出,得到 JING

  •  ppa[-2] 等价于 *(ppa-2)

printf("%s, ", *ppa[-2]+3);

根据上面的可知,ppa  此时指向 pa+2 ,执行 ppa[-2](ppa+2)-2 = ppa,故 ppa 指向 pa 的首地址,即指向 pa[0] 的地址。

*ppa[-2]

 取出 a[3] 的内容,a[3] 又指向字符串 "GUANGZHOU",所以输出 GUANGZHOU

*ppa[-2] +3

 由于其输出 GUANGZHOU,对其 +3 使得指针向后移动 3 位,指针指向 N,对其进行输出,得到 NGZHOU.。

  • ppa[-1][-1]等价于*(*(ppa-1)-1),ppa[-1] 等价于 *(ppa-1)

printf("%s", ppa[-1][-1]+1);

 经过前面的操作, ppa 此时指向 pa[2]

当执行 ppa[-1] ,相当于 *(ppa -1)。所以其将会指向数组 pa[1] 。取出内容 pa[1]pa[1] 又指向 a[2] 

ppa[-1][-1]   等价于 *(ppa[-1]-1)

 在向前移动一次,移动后指向 a[1] ,取出内容 a[1] 的内容,a[1] 又指向字符串 SHENZHEN

ppa[-1][-1]+1

 由于其输出 SHENZHEN,对其 +1 使得指针向后移动 1 位,指针指向 H,对其进行输出,得到 HENZHEN。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xa_L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值