大、小端字节序存储

一、概念

        大小端描述存储多字节数据在计算机内存中的字节顺序的概念(只是字节顺序,不是二进制顺序)

二、什么是大、小端

1、地址存放:

                        由低地址到高地址:

2、高位与低位:

                        看下图就是,1是百万位 属于高位  7是个位属于低位

3、大小端概念:

大端字节序存储:      将一个数据的低位字节放在高地址处,高位字节放在低地址处;

小端字节序存储:      将一个数据的高位字节放在高地址处,低位字节放在低地址处;


4、例子:

int redd(void)
{
	int a = 1;
	//取出a的地址,转变为char* 再解引用,char* 的访问权限为1,访问一个字节
	return *(char*)&a;
}

int main()
{
	int ret = redd();
	if (ret == 0)
	{
		printf("大端\n");
	}
	else
	{
		printf("小端\n");
	}
	return 0;
}

举个例子:以vs编译器为例,在这里先创造一个int型变量

 在vs中便于观察在内存中是以16进制展示(内部原理还是二进制,进行计算也由二进制来实现)

这个就是取a的地址,发现是小端字节序存储

三、如果碰到一个题目:请问这个编译器是大端还是小端字节序存储?

方法一:建立函数通过对地址的解引用来判断

如下:a = 1 的二进制变成十六进制是这样的——>

图1:

 若是大端就是上面这个图,如果是小端 就是下面的图——>

图2:

        我们将a的地址解引用,再强转变为 char* 的地址,访问的就是第一个字节的地址,若是返回的是1就是图2,返回的是0就是图1

代码如下:

int redd(void)
{
	int a = 1;
	//取出a的地址,转变为char* 再解引用,char* 的访问权限为1,访问一个字节,解引用就是第一个字节的内容
	return *(char*)&a;
}

int main()
{
	int ret = redd();
	if (ret == 0)
	{
		printf("大端\n");
	}
	else
	{
		printf("小端\n");
	}
	return 0;
}

方法二:联合体来确定

因为联合体是多个对象共用一个内存,所以更改一个数的值,其他值也会发生改变(是不是像极了高中地理的一句话:牵一动而发动全身

int redd(void)
{
	union Un {
		char a;
		int i;
	}u;
	//将i赋值为1 十六进制 00  00  00  01;
	//小端:01 00 00 00
	//大端:00 00 00 01
	u.i = 1;
    //返回char 的 a
	return u.a;
}

int main()
{
	int ret = redd();
	if (ret == 0)
	{
		printf("大端\n");
	}
	else
	{
		printf("小端\n");
	}
	return 0;
}

若是                       小端就是1          大端就是0

 

### 嵌入式系统中小端字节序的概念及应用 #### 小端字节序定义 字节序(Big Endian)和小端字节序(Little Endian)是描述多字节数据在计算机内存中存储顺序的方式。对于一个多字节的数据,例如一个32位整数,在端模式下,最高有效字节被存放在最低地址处;而在小端模式下,则相反,最低有效字节被存放在最低地址处[^2]。 #### 区别 两者的根本区别在于它们如何解释多字节对象的存储位置: - **字节序**:高位字节优先存储于低地址。 - **小端字节序**:低位字节优先存储于低地址。 这种差异直接影响到跨平台间的数据交换以及硬件设计的选择。当不同架构之间进行通信时,如果不统一字节序可能会导致错误解析接收到的信息[^1]。 #### 应用场景 在嵌入式领域内,字节序的应用非常广泛,尤其是在以下几个方面: - 数据传输过程中确保接收方能够按照发送方预期的方式来解读消息内容; - 文件格式规定特定编码方式以便兼容多种设备读取; - 设备驱动程序编写需考虑目标处理器支持何种类型的字节序列从而正确操作外设寄存器等资源。 #### 转换方法 实现小端之间的相互转变可以通过软件层面完成也可以借助专门指令集加速处理速度。以下是几种常见的做法: ##### 使用标准库函数 C/C++语言提供了几个用于改变主机默认字节次序至网络通用形式(通常是big-endian)的标准APIs, 如htonl(), htons() ,ntohl(), ntohs(). 这些功能可以方便快捷地解决因体系结构引起的问题. ```c #include <arpa/inet.h> uint32_t host_to_network_long(uint32_t hostlong){ return htonl(hostlong); } ``` ##### 手动重组字节 另一种更为灵活但可能效率较低的方法就是手动调整每一个组成部分的位置关系直到达到期望的结果为止。这种方法尤其适用于那些没有现成工具可用的情况或者是针对特殊需求定制解决方案的时候[^3]。 ```python import struct def float_endian_swap(f): packed = struct.pack('f', f) swapped_bytes = bytearray(packed)[::-1] result = struct.unpack('f', bytes(swapped_bytes))[0] return result ``` 上述Python代码片段展示了如何利用`struct`模块先将浮点数值打包成二进制表示然后再颠倒其内部组成单元最终得到反转后的版本。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值