You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的深层原因

这里的核心是指针类型转换导致的跨字节读取,再结合字节序的影响,咱们一步步拆解:

  1. 类型大小的差异
    在当前主流的64位系统中,int通常占4字节,long占8字节。当你把int*类型的&array[1]赋值给long*类型的longPtr时,相当于告诉编译器:“从这个地址开始,把接下来的8个字节当作一个long类型的值来解析”。

  2. 数组的连续内存布局
    数组array在内存中是连续存储的,每个int元素占4字节。以x86架构默认的小端字节序为例,它的内存内容(十六进制)是这样的:

    起始地址存储的字节序列对应数组元素
    &array[0]00 00 00 00array[0] = 0
    &array[1]01 00 00 00array[1] = 1
    &array[2]02 00 00 00array[2] = 2
    .........
  3. 拼接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,这就是你看到的精确数值。

  4. 重要提醒:这属于未定义行为!
    虽然这次刚好得到了固定结果,但本质上你已经越界访问了array[1]之外的内存(array[2]的空间)。如果数组后面的内存被其他变量占用,或者系统是大端字节序,输出结果会完全不同。这种跨类型的指针转换和越界读取在C标准中属于未定义行为,实际开发中一定要避免。

内容的提问来源于stack exchange,提问作者AndrejCoding

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:13:18