编写字节序转换函数(大端转小端)
基本概念
大端和小端是存储多字节数据类型(int、float等)的两种方式。
计算机中是以字节为基本单位,每个地址单元都对应着一个字节,一个字节为8bit。但是在c语言中,除了8bit的char之外,还有16bit的short型… 还有位数大于8位的处理器… 存在如何将多个字节安排的问题,因此就出现了大端存储模式和小端存储模式。
小端:高数据位存在内存的高地址位置;在小端机器中,多字节数据类型的二进制存储的最后一个字节首先存储
大端:高数据位存在内存的低地址位置;在大端机器中首先存储第一个字节
假设整数被存储为4字节。那么一个值为0x01234567
的变量x将被存储如下:
从左往右是低地址到高地址
编码实现
// uint32_t num = 0x12345678
// 方法1:
void swap_endian(uint32_t num) {
// Swap endian (big to little) or (little to big)
uint32_t b0, b1, b2, b3;
uint32_t res;
b0 = (num & 0x000000ff) << 24;
b1 = (num & 0x0000ff00) << 8;
b2 = (num & 0x00ff0000) >> 8;
b3 = (num & 0xff000000) >> 24;
res = b0 | b1 | b2 | b3;
printf("%" PRIX32 "\n", res);
}
// 将低8位(0~8位)左移24位,变成高8位;8~16位左移8位变成16~24位;
// 将原高8位、高16位右移,变成了新的低8位和低16位
// 移位操作后面是否带u结果一样,<< 24u
// 或者也可以简写 不定义变量b
// 方法2:
void swap_endian2(unit32_t num) {
// 大端转小端
uint8_t b[4];
b[0] = (uint8_t) (num >> 0); // int32转int8保留低位
b[1] = (uint8_t) (num >> 8);
b[2] = (uint8_t) (num >> 16);
b[3] = (uint8_t) (num >> 24);
}
// 32位数应存放在4个字节字段中
// b[0]是低地址位置
// 另外一种写法 我不太理解!!!求大佬帮忙看看
void test() {
unit32_t num = 0x12345678;
uint32_t ret;
uint8_t *tmp = (uint8_t*)&ret; // 把指针步长变成8
tmp[0] = num >> 0;
tmp[1] = num >> 8;
tmp[2] = num >> 16;
tmp[3] = num >> 24;
printf("method2: %x-%x-%x-%x, ret:%x\n",tmp[0],tmp[1],tmp[2],tmp[3],ret);
// 打印结果为 method2: 78-56-34-12, ret:12345678 这样结果应该是不对的
// 我不理解这里,为啥ret没有按照tmp[0]temp[1]tmp[2]temp[3]的顺序打印呢???
// 要改成
// tmp[0] = num >> 24;
// tmp[1] = num >> 16;
// tmp[2] = num >> 8;
// tmp[3] = num >> 0;
return ret;
}