C语言初学者笔记【数据在内存中的存储】


前言

介绍C语言中数据在内存中的存储,不同类型的数据存储方式各有不同,相关题目较为复杂,需要深入了解


一、整数存储

1、表示方法

  • 原码:直接转换的二进制(最高位为符号位,0正1负)
    • 例:-5 → 原码 10000101
  • 反码:符号位不变,其余位取反
    • -5 → 反码 11111010
  • 补码:反码+1(内存实际存储形式)
    • -5 → 补码 11111011
  • 正数:原码=反码=补码

2、存储原因

  • 统一处理符号位与数值域
  • 加法器可处理减法(A - B = A + (-B的补码)
  • 补码与原码转换逻辑一致,节省硬件

3、练习题解析

练习1: char a=-1; signed char b=-1; unsigned char c=-1;

printf("a=%d,b=%d,c=%d",a,b,c); // 输出:a=-1,b=-1,c=255

解析

  • a, b 是有符号 char:-1 补码 11111111 → 整型提升为 0xFFFFFFFF(-1)
  • c 是无符号 char:11111111 → 整型提升为 0x000000FF(255)

练习2: char a = -128;char a = 128;

printf("%u\n",a); // 均输出 4294967168

解析

  • -128 补码:10000000 → 整型提升为 0xFFFFFF80(无符号值 4294967168)
  • 128 二进制 10000000 → char 截断为 -128 → 同上

练习2.3.5: char a[1000]; a[i] = -1-i;

printf("%d",strlen(a)); // 输出 255

解析

  • 数组值变化:-1, -2, ..., -128, 127, 126, ..., 0strlen0 停止)
  • 循环路径:-128 → 127 → ... → 0,共 255 个非零值
内存示意图:
a[0] = -1  → 0xFF
a[1] = -2  → 0xFE
...
a[127] = -128 → 0x80
a[128] = 127 → 0x7F
...
a[255] = 0   → 停止

练习2.3.6: 小端环境下 int a[4] = {1,2,3,4};

int *ptr1 = (int*)(&a + 1);     // 指向数组末尾后
int *ptr2 = (int*)((int)a + 1); // 从a[0]的第二个字节开始
printf("%x,%x", ptr1[-1], *ptr2); // 输出:4, 2000000

解析

  • ptr1[-1] = a[3] = 4
  • *ptr2 的内存解析(小端布局):
    a[0] 的字节:01 00 00 00  // 小端存储 0x00000001
    a[1] 的字节:02 00 00 00  // 小端存储 0x00000002
    从 a[0]+1 地址取4字节:00 00 00 02 → 小端解释为 0x02000000
    

二、大小端字节序

1、核心概念

  • 大端模式:数据高位存低地址(人类阅读顺序)
    例:0x1122 → 内存:[11] [22]
  • 小端模式:数据低位存低地址(计算机处理高效)
    例:0x1122 → 内存:[22] [11]

2、判断程序

// 方法1:指针强制转换
int check_sys() {
    int i = 1;
    return *(char*)&i;  // 取首字节(小端返回1,大端返回0)
}

// 方法2:联合体共享内存
int check_sys() {
    union { int i; char c; } un;
    un.i = 1;
    return un.c;  // char c读取int的首字节
}

三、浮点数存储(IEEE 754)

1、存储公式

[ V = (-1)^S \times M \times 2^E ]

  • S:符号位(1 bit)
  • M:有效数字(存时省略开头的 1
  • E:指数(存时加中间值 127/1023

2、内存布局

类型SEM
float1 bit8 bit23 bit
double1 bit11 bit52 bit

3、指数 E 的三种情况

  • E不全0/不全1:真实值 = E - 127,M 补 1.
    例:0.5S=0, E=126, M=0...0
  • E全0:真实值 = 1-127,M 不加 1.(表 ±0 或极小值)
  • E全1:表 ±∞(M全0时)

4、练习题解析

int n = 9;
float *pFloat = (float*)&n;
printf("%f\n", *pFloat); // 输出 0.000000

*pFloat = 9.0;
printf("%d\n", n);       // 输出 1091567616

解析

  • 整数 9 转浮点
    • 内存 00000000 00000000 00000000 00001001
    • 拆分:S=0, E=00000000 (全0), M=000...1001
    • 公式: ( V = 1.001_2 \times 2^{-126} ) → 极小值 ≈0.0
  • 浮点 9.0 转整数
    • 9.0 = 1.001_2 × 2^3S=0, E=3+127=130 (10000010), M=001...0
    • 内存:0 10000010 00100000000000000000000
    • 转为整数:01000001000100000000000000000000_2 = 1091567616

关键总结

主题核心要点应用场景
整数存储内存存补码,统一加减法负数处理、位运算
大小端字节序决定多字节数据排列网络传输、跨平台数据解析
浮点数存储IEEE 754 三段式结构,E 需校正科学计算、精度控制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值