C语言:为何第一个printf输出1,第二个输出8589934593?
为什么long指针读取int地址会输出8589934593?
先把你的代码格式化一下,方便咱们分析:
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]){ int *intPtr = NULL; long *longPtr = NULL; int array[5] = {0,1,2,3,4}; intPtr = &array[1]; longPtr = &array[1]; printf("%d\n", *intPtr); printf("%ld\n", *longPtr); }
第一个printf输出1的原因
这个逻辑很直白:
intPtr是int*类型,精准指向array[1]的地址,而array[1]的初始值就是1。- 用
%d格式化输出*intPtr,就是直接读取这个int类型的数值,所以自然输出1。
第二个printf输出8589934593的深层原因
这里的核心是指针类型转换导致的跨字节读取,再结合字节序的影响,咱们一步步拆解:
类型大小的差异
在当前主流的64位系统中,int通常占4字节,long占8字节。当你把int*类型的&array[1]赋值给long*类型的longPtr时,相当于告诉编译器:“从这个地址开始,把接下来的8个字节当作一个long类型的值来解析”。数组的连续内存布局
数组array在内存中是连续存储的,每个int元素占4字节。以x86架构默认的小端字节序为例,它的内存内容(十六进制)是这样的:起始地址 存储的字节序列 对应数组元素 &array[0] 00 00 00 00 array[0] = 0 &array[1] 01 00 00 00 array[1] = 1 &array[2] 02 00 00 00 array[2] = 2 ... ... ... 拼接8字节成long值
longPtr指向&array[1],所以它会读取从这个地址开始的8个字节——也就是array[1]的4字节(01 00 00 00)加上array[2]的4字节(02 00 00 00)。
小端序的规则是“低字节存放在内存低地址”,所以这8个字节对应的long值二进制是:00000000 00000000 00000000 00000010 00000000 00000000 00000000 00000001转换成十进制就是:
2 * 2^32 + 1 = 8589934592 + 1 = 8589934593,这就是你看到的精确数值。重要提醒:这属于未定义行为!
虽然这次刚好得到了固定结果,但本质上你已经越界访问了array[1]之外的内存(array[2]的空间)。如果数组后面的内存被其他变量占用,或者系统是大端字节序,输出结果会完全不同。这种跨类型的指针转换和越界读取在C标准中属于未定义行为,实际开发中一定要避免。
内容的提问来源于stack exchange,提问作者AndrejCoding
相关产品推荐
相关产品推荐

