其实你也懂指针计算

  在C语言中,指针运算是一个让很多人感到无助的东西,尤其在结合上数组的下标运算和指针的多级访问,更加让指针这个东西更加神秘,今天我们就来仔细的看一下指针之间的指向关系。

下面来看一下这道题:

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

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

首先我们需要分析出这个指针之间的指向关系


接下来我们先看第一个表达式**++cpp,首先执行++运算cpp现在指向加1,进行一次解引

用拿到的是cp中c+2的内容,又因为c+2里面存的POINT的地址,以S%输出时,依次取到

的就是POINT这个字符串,但是由于++运算的副作用,它的后效性使它指向CPC+2的位

置,执行完后的操作图如下所示


接下来我们来看第二个表达式*--*++cpp+3,首先来分析一下各个运算符的优先级,先执

行自加,然后再解引用,再减减,在解引用,最后在执行3,下面我们来仔细的分析一下

各步的运行和他们产生的结果,++cp使它由c+2指向c+1,然后进行一次解引用操作再减

减使它由c+1指向c的位置,在解引用指向的是c所指的字符串的首元素的地址,结果+3

再使指针向后偏移3个char,z指向E这个元素的地址,然后以%S输出时,就是他后面的字

符,同样++之后也会产生副作用,这点非常重要,一定要注意。所以结果为ER,操作流

程见下图:


接下来我们再来看*cpp[-2]+3,既然是讨论指针我们就现将这个表达式化成等价的指针

表达式*(*(cpp-2))+3,采用同样的方法,我们拿到指针的问题先来分析它的运算符的执行

顺序,由于括号的优先级较高,先执行cpp-2,在解引用,完了在解引用,最后在+3

cpp-2使得指针指向c+3的位置,两次解引用之后指向FIRST这个字符串的首地址F,+3

使得指针向后偏移3个char,指向s的地址,再以%s的形式输出,所以结果为ST,操作

流程见下图:


我们再来看最后一个表达式cpp[-1][-1]+1,我们先将它化成等价的指针表达式

*((*(cpp-1))-1)+1,分析它的运算符执行顺序,先是内层括号中-1解引用,再是外层括号

中-1解引用,所得值在+1,内层cpp-1使得使得它的cpp指向c+2解引用,外层再-1解引

用指向NEW字符串的首地址,+1使得指针向后偏移一个char,指向E的地址,再以%s的

形式输出,所以结果为EW,操作流程见下图:


最后我们再来验证一下我们的结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

double_happiness

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

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

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

打赏作者

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

抵扣说明:

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

余额充值