C语言数据在内存中的存储(后续会持续优化)

在 C 语言编程中,数据在内存里到底怎么存是核心底层知识点,它直接决定了代码的运行结果、数据溢出、字节序问题,也是面试高频考点。今天就把整数存储、大小端字节序、浮点数存储一次性讲透。


目录

  1. 前言:为什么要学内存存储
  2. 整数在内存中的存储
  3. 大小端字节序与判断
  4. 经典整型内存练习题解析
  5. 浮点数在内存中的存储(IEEE 754)
  6. 浮点数经典面试题详解
  7. 全文总结
  8. 面试高频考点速记

1. 前言:为什么要学内存存储

C 语言是贴近硬件的语言,数据溢出、符号扩展、字节序、指针越界、类型强转等问题,本质都来自内存存储规则。搞懂这一章,你才能真正看懂底层、写稳代码、过面试。


2. 整数在内存中的存储

2.1 原码、反码、补码

整数的二进制表示有三种:原码、反码、补码 。有符号整数最高位是符号位:0 表示正数,1 表示负数。

  • 正整数:原码 = 反码 = 补码
  • 负整数:
    • 原码:直接翻译二进制
    • 反码:符号位不变,其余按位取反
    • 补码:反码 + 1

2.2 整数为什么存补码

C 语言中,整数在内存只存补码,原因:

  1. 统一处理符号位与数值位
  2. CPU 只有加法器,补码让加减法统一实现
  3. 补码与原码互转不需要额外硬件电路

3. 大小端字节序与判断

3.1 什么是大小端

超过 1 字节的数据,存储时有字节顺序:

  • 大端:高位字节存低地址,低位字节存高地址
  • 小端:低位字节存低地址,高位字节存高地址

示例:int a = 0x11223344

  • 大端:11 22 33 44
  • 小端:44 33 22 11(X86 默认小端)

3.2 为什么有大小端

计算机以字节为单位寻址,而处理器寄存器宽度大于 1 字节,多字节数据必须规定排放顺序,因此出现大小端。

3.3 代码判断机器字节序

c

运行

复制代码
// 方法1:指针强转解引用
int check_sys() {
    int i = 1;
    return *(char *)&i;
}

// 方法2:共用体(union)
int check_sys() {
    union {
        int i;
        char c;
    }un;
    un.i = 1;
    return un.c;
}

int main() {
    int ret = check_sys();
    if(ret == 1)
        printf("小端\n");
    else
        printf("大端\n");
    return 0;
}

返回 1 → 小端;返回 0 → 大端。


4. 经典整型内存练习题解析

4.1 char 正负值打印

c

运行

复制代码
char a = -1;
signed char b = -1;
unsigned char c = -1;
printf("%d,%d,%d",a,b,c); 
// 输出:-1,-1,255

4.2 char 越界问题

c

运行

复制代码
char a = -128;
printf("%u\n",a); 
// 输出:4294967168

4.3 无符号死循环陷阱

复制代码
unsigned char i = 0;
for(i=0; i<=255; i++){
    printf("hello world\n");
}
// 无限循环

4.4 数组指针 + 字节序综合题

复制代码
// X86小端环境
int a[4] = {1,2,3,4};
int *ptr1 = (int *)(&a + 1);
int *ptr2 = (int *)((int)a + 1);
printf("%x,%x", ptr1[-1], *ptr2);
// 输出:4,2000000

5. 浮点数在内存中的存储(IEEE 754)

5.1 存储标准公式

任意二进制浮点数:V = (-1)^S * M * 2^E

  • S:符号位(0 正 1 负)
  • M:有效数字(1≤M<2)
  • E:指数位

5.2 float /double 存储布局

  • float(32 位):1 位 S + 8 位 E + 23 位 M
  • double(64 位):1 位 S + 11 位 E + 52 位 M

5.3 存储规则

  1. M 省略首位 1:只存小数部分,提升精度
  2. E 加偏移量:float+127,double+1023,兼容负数指数

5.4 读取时 E 的三种情况

  1. E 不全 0 不全 1:常规解析,E-127 得真实值
  2. E 全 0:表示 ±0 或极小数字,E=1-127
  3. E 全 1:M 全 0 表示无穷大,否则为 NaN

6. 浮点数经典面试题详解

复制代码
int n = 9;
float *p = (float *)&n;
printf("%d %f\n", n, *p); 
// 输出:9 0.000000

*p = 9.0;
printf("%d %f\n", n, *p); 
// 输出:1091567616 9.000000

解析:

  • 整数 9 按浮点数解析:E 全 0,结果趋近于 0
  • 浮点数 9.0 按 IEEE 754 存储,转整数解析为 1091567616

7. 全文总结

  1. 整数在内存中以补码存储,统一符号与运算
  2. 多字节数据存在大小端,X86 默认小端
  3. 无符号数溢出、char 越界、符号扩展是常见坑
  4. 浮点数严格遵循IEEE 754,按 S/E/M 分段存储
  5. 整型与浮点强转,内存不变、解析规则不同

8. 面试高频考点速记

  1. 整数为什么存补码?
  2. 大小端概念 + 手写判断代码
  3. char 越界、无符号死循环原因
  4. IEEE 754 浮点数存储结构
  5. int 与 float 互转面试题原理
相关推荐
wuyk55515 小时前
嵌入式驱动开发:量产级工程化实战(第9篇)——低功耗下的通信可靠性
c语言·驱动开发·stm32·单片机·嵌入式硬件
学逆向的16 小时前
C 突破编译器限制
c语言·开发语言·网络安全
endeavor1217 小时前
can总线(五)
c语言·stm32·单片机·can
老王爱玩车19 小时前
预处理详解
c语言·开发语言·学习
学逆向的20 小时前
C 控制台指令
c语言·开发语言·网络安全
沫璃染墨20 小时前
从零入门数据结构与算法(一):复杂度分析——从算法效率到时间与空间复杂度
c语言·开发语言·数据结构·笔记·算法·飞书
想做小南娘,发现自己是女生喵20 小时前
第三周学习文档 Linux C 多进程与多线程
linux·c语言·学习
听风若依21 小时前
函数栈帧的创建与销毁-重置版
c语言·学习
水饺编程1 天前
第2章:Linux 基础,pwd 命令
linux·c语言·汇编
鱼很腾apoc1 天前
【MySQL】 第1期 从核心概念到表约束全解析
linux·c语言·数据库·学习·mysql