请解释p[-i]与printf("%d", p[-i])的作用,我的猜想是否正确?
嘿,作为编程初学者能留意到这个语法细节真的超棒!你的猜想完全正确,不过咱们可以把这个知识点拆解得更透彻,顺便补充一些相关的实用细节~
先搞懂
p[-i]到底是什么 在C语言里,数组和指针其实是紧密关联的:数组名本质上是指向数组第一个元素的指针。而我们平时写的p[n]这种数组式索引,其实是C语言给我们的语法糖——它等价于*(p + n)。意思是:把指针p向后偏移n个元素的长度(指针会自动根据指向的类型计算字节数,不用你手动算),然后解引用这个地址,拿到对应位置的值。
那p[-i]就很好推导了:它等价于*(p - i)。也就是把指针p向前偏移i个元素的位置,然后解引用获取该位置的数值。
给你举个直观的例子:
int numbers[] = {10, 20, 30, 40, 50}; int *p = &numbers[3]; // 此时p指向数组里的40 printf("%d\n", p[-1]); // 等价于*(p-1),也就是numbers[2],输出30 printf("%d\n", p[-2]); // 等价于*(p-2),也就是numbers[1],输出20
⚠️ 重要提醒:你必须保证p - i指向的是合法的内存地址(比如数组的有效范围内),不然会触发「未定义行为」——程序可能崩溃、输出乱码,甚至出现更诡异的问题。比如如果p是指向数组第一个元素的指针,p[-1]就会指向数组前面的非法内存,绝对不能这么写!
再看
printf("%d", p[-i])的作用 这个就很直接了:它先计算出p[-i]对应的整数值,然后用%d格式符把这个整数输出到控制台。比如上面例子里的printf("%d", p[-1]),就是先拿到30,再把30打印出来。
一些额外的相关知识点
- 指针的索引不只是能写正数,其实可以是任何整数(正、负、零),只要对应的内存地址合法就行。比如
p[0]就等价于*p,也就是指针当前指向的元素。 - 数组的索引本质也是指针运算:比如
numbers[i]等价于*(numbers + i),但如果直接写numbers[-1]就会越界,因为numbers是指向数组首元素的指针,向前偏移1个元素就超出数组范围了。只有当指针p本身指向数组中间的元素时,p[-i]才可能合法。 - 这种写法在某些场景下很实用:比如当你有一个指针指向数组的中间位置,需要访问前面的元素时,用
p[-i]比手动计算&numbers[k - i]要简洁得多。
内容的提问来源于stack exchange,提问作者Yash
相关产品推荐
相关产品推荐

