大小端转换

大小端转换


1 概念

大小端是设备存储数据的方式,分为大端存储小端存储

  • 大端存储是指数据的高字节存放在低地址处,低位字节放在高地址。
  • 小端存储与之相反,高字节存放在高地址,低位字节存放在低地址。

举个例子

int a = 0x12345678;

变量a中的数据,0x1为高字节数据,0x8为低字节数据,0x12345678数据从高位到低位依次为0x1、0x2、0x3、0x4、0x5、0x6、0x7、0x8。一个int类型的数据占4个字节,每个字节占1个内存地址,于是变量a在内存中占用了4个地址,假定4个地址分别为0x01、0x02、0x03、0x04。
情况1:小端存储

	*((char*)0x01) = 0x78;
	*((char*)0x02) = 0x56;
	*((char*)0x03) = 0x34;
	*((char*)0x04) = 0x12;

情况2:大端存储

	*((char*)0x01) = 0x12;
	*((char*)0x02) = 0x34;
	*((char*)0x03) = 0x56;
	*((char*)0x04) = 0x78;

依据上述的结果,大端存储相当于将数据按字符串存储的方式正序放置,小端存储则是将数据按字符串存储的方式倒序放置。转成字符串数组的形式大概如下:

char str[4];
/* 大端存储 */
str[0] = 0x12, str[1] = 0x34, str[2] = 0x56, str[3] = 0x78;

/* 小端存储 */
str[0] = 0x78, str[1] = 0x56, str[2] = 0x34, str[3] = 0x12;

2 判定设备存储方式

一般情况下我们需要先确认当前设备是哪种存储模式,而判定的方式很简单。定义一个int类型的数据并初始化1个大一些的值,之后分别打印单个地址中存放的数据,再根据大小端的定义人工判定。例程如下:

	int a = 0x12345678;
    char* pt = (char* )&a;

    printf("%p, %x\n", pt, *(pt));
    printf("%p, %x\n", pt+1, *(pt+1));
    printf("%p, %x\n", pt+2, *(pt+2));
    printf("%p, %x\n", pt+3, *(pt+3));

目前市面上大部分硬件芯片都是小端存储。


3 适用场景

从大小端的概念上看,如果数据是单字节,那么就没有大小端的问题,但如果传输的数据是多字节类型的时候就要考虑大小端情况。大部分情况下是设备与云端数据交互时要处理大小端,以及上下位机交互数据时,总得来说只有在数据交互通信时才需要考虑大小端转换。


4 大小端转换

建议使用共用体,如下所示:

/* 将1个字变量拆分成4个字节,以此可以用来处理大小端问题 */
typedef union _word_split {
	uint32_t word;
	uint8_t byte[4];
} WORD_SPLIT_u;

WORD_SPLIT_u zero_time_u = {.word = 1641225600};
printf("%p, %x\n", byte, byte[0]);
printf("%p, %x\n", byte+1, byte[1]);
printf("%p, %x\n", byte+2, byte[2]);
printf("%p, %x\n", byte+3, byte[3]);

当我们将整型数据赋值到word成员中,那么byte成员就是单字节的拆分。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值