在 C 语言编程中,数据在内存里到底怎么存是核心底层知识点,它直接决定了代码的运行结果、数据溢出、字节序问题,也是面试高频考点。今天就把整数存储、大小端字节序、浮点数存储一次性讲透。
目录
- 前言:为什么要学内存存储
- 整数在内存中的存储
- 大小端字节序与判断
- 经典整型内存练习题解析
- 浮点数在内存中的存储(IEEE 754)
- 浮点数经典面试题详解
- 全文总结
- 面试高频考点速记
1. 前言:为什么要学内存存储
C 语言是贴近硬件的语言,数据溢出、符号扩展、字节序、指针越界、类型强转等问题,本质都来自内存存储规则。搞懂这一章,你才能真正看懂底层、写稳代码、过面试。
2. 整数在内存中的存储
2.1 原码、反码、补码
整数的二进制表示有三种:原码、反码、补码 。有符号整数最高位是符号位:0 表示正数,1 表示负数。
- 正整数:原码 = 反码 = 补码
- 负整数:
- 原码:直接翻译二进制
- 反码:符号位不变,其余按位取反
- 补码:反码 + 1
2.2 整数为什么存补码
C 语言中,整数在内存只存补码,原因:
- 统一处理符号位与数值位
- CPU 只有加法器,补码让加减法统一实现
- 补码与原码互转不需要额外硬件电路
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 存储规则
- M 省略首位 1:只存小数部分,提升精度
- E 加偏移量:float+127,double+1023,兼容负数指数
5.4 读取时 E 的三种情况
- E 不全 0 不全 1:常规解析,E-127 得真实值
- E 全 0:表示 ±0 或极小数字,E=1-127
- 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. 全文总结
- 整数在内存中以补码存储,统一符号与运算
- 多字节数据存在大小端,X86 默认小端
- 无符号数溢出、char 越界、符号扩展是常见坑
- 浮点数严格遵循IEEE 754,按 S/E/M 分段存储
- 整型与浮点强转,内存不变、解析规则不同
8. 面试高频考点速记
- 整数为什么存补码?
- 大小端概念 + 手写判断代码
- char 越界、无符号死循环原因
- IEEE 754 浮点数存储结构
- int 与 float 互转面试题原理