字节序大小端
概述
- 1. 大小端是什么
- 2. 如何判断本机大小端
- 3.大小端转换
1. 大小端是什么
在计算机科学中,大小端(Endian)是一个术语,用于描述多字节数据在内存中的存储顺序。具体地说,它指的是一个数据单元(如整数、浮点数等)的字节如何在内存地址中排列。这个术语来源于“Endian”一词,它源自于乔纳森·斯威夫特的小说《格列佛游记》中的一个小岛,岛上的居民在争论吃鸡蛋时应该从大头(Big-End)开始还是从小头(Little-End)开始,这反映了一种在细节上争执不下的文化。
大端(Big-Endian)
在大端字节序中,数据的最高有效字节(MSB,Most Significant Byte)存储在内存的低地址端,而最低有效字节(LSB,Least Significant Byte)存储在内存的高地址端。这种顺序与人类阅读的顺序相似,即从左到右,从高位到低位。
小端(Little-Endian)
在小端字节序中,数据的最低有效字节(LSB)存储在内存的低地址端,而最高有效字节(MSB)存储在内存的高地址端。这与大端字节序完全相反。
2. 如何判断本机大小端
#include <iostream> // 函数用于判断本机的大小端模式
bool isLittleEndian() { // 定义一个联合体,包含一个整型和一个字符数组 union { uint32_t i; char c[4]; } test; // 给整型赋值,这里使用了一个十六进制数,方便查看其在内存中的存储方式 test.i = 0x01020304; // 检查字符数组的第一个字节 // 如果是小端模式,低地址处存储的是低位字节,即0x04 // 如果是大端模式,低地址处存储的是高位字节,即0x01 return test.c[0] == 4; // 注意这里直接比较的是字符的ASCII值,'4'的ASCII值是52,但这里我们实际上是在比较整数值4
} int main() { if (isLittleEndian()) { std::cout << "This machine is little endian." << std::endl; } else { std::cout << "This machine is big endian." << std::endl; } return 0;
}
3.大小端转换
#include <iostream>// 大小端类型
enum EndianType{eEndianLittle,eEndianBig
};// 函数用于判断本机的大小端模式
bool isLittleEndian() { union { uint32_t i; char c[4]; } test; test.i = 0x01020304; return test.c[0] == 4;
}// 返回本机大小端
const EndianType& LocalEndianType()
{static EndianType type = isLittleEndian() ? eEndianLittle : eEndianBig;return type;
}// 转换大小端
using Byte = unsigned char;
void toEndian(const EndianType& type, Byte* begin, int size)
{if (size > 1 && LocalEndianType()!=type){Byte* beg = begin, *end = begin + size - 1;while(beg < end){std::swap(*beg++,*end--);}}
}int main()
{union { uint32_t i; unsigned char sz[4]; } test; test.i = 0x01020304;std::cout << (int)test.sz[0] << std::endl;toEndian(eEndianBig, test.sz, 4);std::cout << (int)test.sz[0] << std::endl;
}