高阶C语言|深度剖析数据在内存中的存储

💬 欢迎讨论:在阅读过程中有任何疑问,欢迎在评论区留言,我们一起交流学习!

👍 点赞、收藏与分享:如果你觉得这篇文章对你有帮助,记得点赞、收藏,并分享给更多对数据存储感兴趣的朋友!

重点

  1. 数据类型详细介绍
  2. 整型在内存中的存储:原码、反码、补码
  3. 大小端字节序介绍及判断
  4. 浮点型在内存中的存储解析

1. 数据类型介绍

在计算机程序中,数据类型不仅决定了变量存储数据的方式,还决定了如何高效地处理这些数据。每种数据类型都有其特定的内存分配规则、范围和使用场景。理解数据类型的基本分类是学习内存存储的第一步。

1.1 数据类型的基本分类
  • 整型家族:用于表示整数值。

    • char:字符类型,通常占 1 字节。用于表示字符或小范围整数。
    • short:短整型,占 2 字节,范围通常为 -32,768 到 32,767。
    • int:整型,占 4 字节,范围通常为 -2,147,483,648 到 2,147,483,647。
    • long:长整型,占 4 或 8 字节(平台依赖),在 64 位系统中通常为 8 字节。
    • long long:更长的整型,占 8 字节,适用于存储更大的整数。
  • 浮点型家族:用于表示带小数点的数字,适用于处理实数。

    • float:单精度浮点数,占 4 字节,提供大约 6 位有效数字的精度。
    • double:双精度浮点数,占 8 字节,提供大约 15 位有效数字的精度。
    • long double:扩展精度浮点数,占 12 或 16 字节,具体取决于平台,提供更高精度。
  • 其他类型

    • void:空类型,用于表示函数的返回类型或无类型的指针。
    • 指针类型:用于存储变量的地址,常见类型有 int*char*float* 等。

这些数据类型的选择不仅影响变量占用的内存大小,还影响程序的性能和计算精度。熟悉不同类型的内存存储规则是理解程序如何高效运行的基础。


2. 整型在内存中的存储

计算机内存以二进制的方式存储数据,整型(如 intshort 等)采用不同的编码方式来表示数值。常见的表示方法有 原码反码补码

2.1 原码、反码、补码
  • 原码:直接将数值按符号位和数值位转换成二进制。对于负数,符号位为 1,正数的符号位为 0

  • 反码:对原码中的数值位取反,符号位不变。反码的主要用途是对负数进行运算。

  • 补码:反码加 1,计算机使用补码来表示负数。补码的使用使得加法器能够统一处理正负数的加法,简化了硬件设计。

在计算机内存中,整数通常以补码形式存储,因为补码运算能够简化加减运算,同时避免了负数处理的复杂性。通过补码,可以实现更高效的运算,并且不需要额外的硬件支持。

2.2 大小端字节序

计算机存储数据时,字节的排列顺序并非一成不变。根据字节存储的高低位顺序,计算机系统有两种常见的字节序:大端字节序小端字节序

  • 大端字节序(Big-endian):将数据的高位字节存储在内存的低地址处,低位字节存储在高地址处。例如,对于一个 32 位的整数 0x11223344,大端存储方式将其存储为:

    地址:0x00  0x01  0x02  0x03  
    数据:  0x11  0x22  0x33  0x44
    
  • 小端字节序(Little-endian):将数据的低位字节存储在内存的低地址处,高位字节存储在高地址处。例如,同样是 0x11223344,小端存储方式将其存储为:

    地址:0x00  0x01  0x02  0x03  
    数据:  0x44  0x33  0x22  0x11
    

不同的计算机体系结构可能采用不同的字节序。例如,x86 架构采用小端字节序,而某些老式的 RISC 架构或网络协议则使用大端字节序。

2.3 判断字节序

以下是一个简单的 C 程序,可以判断当前系统使用的是大端字节序还是小端字节序:

#include <stdio.h>

int check_endian() {
    int num = 1;
    return (*(char *)&num == 1);
}

int main() {
    if (check_endian()) {
        printf("小端字节序\n");
    } else {
        printf("大端字节序\n");
    }
    return 0;
}

该程序通过查看整数 1 在内存中的存储情况来判断字节序。如果 1 的最低有效字节(LSB)存储在低地址,则为小端字节序,否则为大端字节序。


3. 浮点型在内存中的存储

浮点数用于表示实数(带小数的数字),在计算机内部采用 IEEE 754 标准 进行存储。该标准规定了浮点数如何用二进制表示,包括符号位、指数位和尾数部分。

3.1 IEEE 754 浮点数标准

浮点数的表示形式为:
[
(-1)^S \times M \times 2^E
]
其中:

  • S:符号位,0 表示正数,1 表示负数。
  • M:尾数(有效数字),大于等于 1 小于 2。
  • E:指数,表示数据需要乘以 2 的多少次方。

对于 32 位的单精度浮点数:

  • 符号位:1 位
  • 指数位:8 位(无符号整数,使用偏移量 127)
  • 尾数位:23 位(有效数字,去除前导 1)

对于 64 位的双精度浮点数:

  • 符号位:1 位
  • 指数位:11 位(使用偏移量 1023)
  • 尾数位:52 位

浮点数的精度和范围受限于其表示位数。由于尾数部分只能表示有限的有效数字,因此浮点数在计算时可能会出现舍入误差。

3.2 浮点数与整数的内存存储差异

浮点数和整数在内存中的存储方式不同,可能导致同一段内存数据被不同类型解读时出现巨大差异。例如:

int n = 9;
float *pFloat = (float *)&n;
printf("n的值为:%d\n", n);          // 输出:9
printf("*pFloat的值为:%f\n", *pFloat);  // 输出:9.000000

在内存中,整数和浮点数使用不同的格式存储,导致相同的内存内容可能被解读为不同的数值。

3.3 浮点数存储示例

以浮点数 9.0 为例,它在 IEEE 754 单精度浮点数格式中的存储过程如下:

  1. 9.0 转化为二进制表示:1001.0,即 1.001 × 2^3
  2. 符号位:S = 0(正数)
  3. 指数位:E = 3 + 127 = 130(偏移量 127)
  4. 尾数位:M = 00100000000000000000000(去除前导 1,保留 23 位)

因此,9.0 在内存中的 32 位表示为:

符号位 | 指数位 | 尾数位
0      | 10000010 | 00100000000000000000000

通过这种方式,计算机可以

在内存中高效存储浮点数。


4. 实战练习

通过实际编程练习,可以加深对内存存储原理的理解:

  1. 练习1:打印 char 类型的溢出情况,观察 char 类型从 -128127 的范围如何影响存储。
  2. 练习2:手动实现整数到二进制(补码)的转换,并观察不同符号的存储效果。
  3. 练习3:在小端和大端机器上分别存储 intfloat 类型的变量,查看它们在内存中的表现。
  4. 练习4:使用位运算检查浮点数的存储结构,深入理解其表示方式。

总结

通过对数据类型、整数和浮点数在内存中存储方式的深入理解,可以更清楚地看到计算机如何高效地处理不同类型的数据。掌握补码、大端字节序、浮点数表示等基本概念,将有助于我们在编程中避免潜在的错误和性能瓶颈。

标题“51单片机通过MPU6050-DMP获取姿态角例程”解析 “51单片机通过MPU6050-DMP获取姿态角例程”是一个基于51系列单片机(一种常见的8位微控制器)的程序示例,用于读取MPU6050传感器的数据,并通过其内置的数字运动处理器(DMP)计算设备的姿态角(如倾斜角度、旋转角度等)。MPU6050是一款集成三轴加速度计和三轴陀螺仪的六自由度传感器,广泛应用于运动控制和姿态检测领域。该例程利用MPU6050的DMP功能,由DMP处理复杂的运动学算法,例如姿态融合,将加速度计和陀螺仪的数据进行整合,从而提供稳定且实时的姿态估计,减轻主控MCU的计算负担。最终,姿态角数据通过LCD1602显示屏以字符形式可视化展示,为用户提供直观的反馈。 从标签“51单片机 6050”可知,该项目主要涉及51单片机和MPU6050传感器这两个关键硬件组件。51单片机基于8051内核,因编程简单、成本低而被广泛应用;MPU6050作为惯性测量单元(IMU),可测量设备的线性和角速度。文件名“51-DMP-NET”可能表示这是一个与51单片机及DMP相关的网络资源或代码库,其中可能包含C语言等适合51单片机的编程语言的源代码、配置文件、用户手册、示例程序,以及可能的调试工具或IDE项目文件。 实现该项目需以下步骤:首先是硬件连接,将51单片机与MPU6050通过I2C接口正确连接,同时将LCD1602连接到51单片机的串行数据线和控制线上;接着是初始化设置,配置51单片机的I/O端口,初始化I2C通信协议,设置MPU6050的工作模式和数据输出速率;然后是DMP配置,启用MPU6050的DMP功能,加载预编译的DMP固件,并设置DMP输出数据的中断;之后是数据读取,通过中断服务程序从DMP接收姿态角数据数据通常以四元数或欧拉角形式呈现;再接着是数据显示,将姿态角数据转换为可读的度数格
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值