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 互转面试题原理
相关推荐
InfinteJustice1 天前
踩坑分享C 语言文件操作全攻略:从基础读写到随机访问与缓冲区原理
c语言·开发语言·microsoft
瑶池酒剑仙1 天前
C++类和对象完全指南:从封装继承多态到内存布局的面向对象宝典(雨夜论道)
c语言·开发语言·c++·visual studio
三品吉他手会点灯1 天前
C语言学习笔记 - 27.C编程预备计算机专业知识 - 什么是字节
c语言·开发语言·笔记·学习
邪修king2 天前
C++ 继承超全详解:核心语法、作用域、默认函数、菱形继承与避坑指南
c语言·c++
djarmy2 天前
C 标准库 `<stdio.h>` 完整函数清单(官方标准 + 常用全部函数)
c语言·c++·算法
handler012 天前
速通蓝桥杯省一: 前缀和&差分(附经典例题)
c语言·c++·笔记·职场和发展·蓝桥杯
谙弆悕博士2 天前
快速学C语言——第 11 章:指针与数组
服务器·c语言·开发语言·学习方法·业界资讯·指针·数组
薇茗2 天前
【初阶数据结构】 左右逢源的分支诗律 二叉树3
c语言·数据结构·二叉树·经典oj面试题
袁雅倩19972 天前
当吸尘器、筋膜枪都用上Type-C,供电方案该怎么选?浅谈PD取电芯片ECP5702的应用
c语言·开发语言·支持向量机·动态规划·推荐算法·最小二乘法·图搜索算法
CHANG_THE_WORLD2 天前
C语言中的 %*s 和 %.*s 和C++的字符串格式化输出
c语言·c++·c#