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 互转面试题原理
相关推荐
wuminyu1 小时前
Java锁机制之park与futex系统级协同机制解析
java·linux·c语言·jvm·c++
caimouse4 小时前
reactos编码规范
c语言·开发语言
AI thought9 小时前
【转】C语言中 -> 是什么意思?
c语言·位移运算符·右移赋值·无符号整数·算术右移
qeen8712 小时前
【C++】类与对象之类的默认成员函数(二)
android·c语言·开发语言·c++·笔记·学习
wuminyu14 小时前
Java锁机制之park和unpark源码剖析
java·linux·c语言·jvm·c++
asdfg125896315 小时前
C 语言中产生伪随机数的标准做法
c语言·开发语言
玖玥拾15 小时前
C/C++ 基础笔记(十一)类的进阶
c语言·c++·设计模式·
Soari16 小时前
llama.cpp更新(b9553):LLM inference in C/C++,本地和云端实现高性能大模型推理
c语言·c++·llama
2601_9611940216 小时前
考研资料电子版|去哪找|网盘
java·c语言·c++·python·考研·php
十月的皮皮17 小时前
C语言学习笔记202606008- 三角形判断(3种方法)
c语言·笔记·学习