为何这段C代码的输出为-3?求技术层面的详细解释
为什么两个数组元素的地址差值会是-3?
嘿,这个问题问到点子上了!咱们一步步拆解背后的逻辑,你就能明白为啥结果是-3了。
首先得明确C语言里指针减法的核心规则:
只有指向**同一数组(或同一连续内存块)**的两个指针相减,结果才是标准定义的——它表示两个指针之间相差的元素个数(不是字节数)。如果是两个完全独立数组的指针相减,这其实属于C标准里的「未定义行为」,不过大多数编译器会按照实际地址差来计算,这也是你得到-3的原因。
接下来看你的代码里的数组布局:
#include<stdio.h> #include<stdlib.h> int main() { int a[4] = {1,2,3,4}; int b[4] = {1,2,3,4}; int n = &b[3] - &a[2]; printf("%d\n", n); return 0; }
你在main函数里声明了两个局部数组a和b,而局部变量在大多数系统中是存储在栈上的,栈的增长方向是从高地址向低地址延伸——也就是说,先声明的变量会被分配在更高的内存地址上。
举个具体的地址例子(假设int占4字节):
- 假设数组
a的起始地址是0x1000,那么a[2]的地址就是0x1000 + 2*4 = 0x1008(因为a[2]是数组的第三个元素,偏移2个int的大小) - 因为栈向下增长,后声明的数组
b会被分配在更低的地址,比如0x0FF0,那么b[3]的地址就是0x0FF0 + 3*4 = 0x0FFC
现在计算指针差值:
- 先算地址的字节差:
0x0FFC - 0x1008 = -12字节 - 指针减法会自动除以元素的大小(这里是
sizeof(int)=4),所以-12 /4 = -3——这就是变量n的值。
最后要提醒一句:虽然这次你得到了-3,但因为不同数组指针相减是未定义行为,换个编译器、换个编译选项甚至换个系统,结果都可能不一样,绝对不能在生产代码里依赖这种行为哦!
内容的提问来源于stack exchange,提问作者neo
相关产品推荐
相关产品推荐

