指针运算代码疑问:为何这段C语言代码输出2 5?
理解这段C代码的指针行为:为什么输出是2 5?
先把咱们要分析的代码贴出来,方便对照查看:
#include <stdio.h> int main(void) { char x[5] = { 1, 2, 3, 4, 5 }; char *ptr = (char*)(&x + 1); printf("%d %d\n", *(x + 1), *(ptr - 1)); return 0; }
我用内存布局可视化+分步拆解的方式帮你搞懂指针的工作逻辑,保证一目了然:
第一步:数组x的内存排布
x是长度为5的char数组,每个元素占1字节。假设它的起始内存地址是0x100(选个好算的地址),那内存里的结构是这样的:
| 内存地址 | 存储的值 | 对应数组元素 |
|---|---|---|
| 0x100 | 1 | x[0] |
| 0x101 | 2 | x[1] |
| 0x102 | 3 | x[2] |
| 0x103 | 4 | x[3] |
| 0x104 | 5 | x[4] |
这里要记住:数组名x本质是指向数组第一个元素的指针,也就是x等价于&x[0],类型是char*。
第二步:搞懂&x + 1的指向
&x是取整个数组x的地址,它的类型是char (*)[5]——也就是一个指向「长度为5的char数组」的指针。
指针加法的核心规则是:按指针指向类型的大小来跳步。
&x指向的是整个数组,数组总大小是5字节,所以&x + 1会直接跳过整个数组,指向数组末尾的下一个位置,也就是地址0x100 + 5 = 0x105。- 之后我们把这个地址强制转换成
char*类型赋值给ptr,所以ptr现在指向地址0x105。
第三步:拆解两个printf参数
第一个参数:*(x + 1)
x是指向x[0]的char*指针,x + 1就是向后移动1个char的长度(1字节),指向x[1]的地址0x101,*(x + 1)就是取这个地址里的值,也就是2。
第二个参数:*(ptr - 1)
ptr是char*类型,ptr - 1就是向前移动1个char的长度(1字节),从0x105挪到0x104,这个地址里存的是x[4]的值5,所以*(ptr - 1)就是5。
最终结论
把这两个值打印出来,自然就是2 5了。核心是要区分指向单个元素的指针和指向整个数组的指针的加法步长差异——前者按单个元素大小跳,后者按整个数组大小跳。
内容的提问来源于stack exchange,提问作者Sanjay Verma
相关产品推荐
相关产品推荐

