大家好,欢迎来到IT知识分享网。
目录
字节序是什么意思
字节序(Byte Order)是指计算机中多字节数据类型(如整型、浮点型等)在内存中存储的顺序。
常见的字节序有两种:
- 大端序(Big-Endian):数据的高位字节存储在内存的低地址处,低位字节存储在内存的高地址处。类比于数字的书写顺序:高位在前,低位在后。
- 小端序(Little-Endian):数据的低位字节存储在内存的低地址处,高位字节存储在内存的高地址处。类比于数字的书写顺序:低位在前,高位在后。
字节序的选择对于数据的解析和传输都非常重要。如果发送方和接收方的字节序不一致,就会导致数据解析错误。因此,在进行跨平台数据交互时,需要明确指定和处理字节序,以确保数据的正确传输和解析。
注:可以在代码中采取条件编译,根据字节序的不同选择不同的成员顺序,以适应不同的字节序要求。这样可以保证在不同的平台上都能正确地解析数据。
不同字节序举例
- 大端序:
- 整数值 0x 在内存中存储为:0x12 0x34 0x56 0x78(由4个字节组成的16进制序列,每个字节都用两个16进制数表示)
- 浮点数值3.14在内存中存储为:0x40 0x48 0xf5 0xc3
- 小端序:
- 整数值 0x 在内存中存储为:0x78 0x56 0x34 0x12
- 浮点数值 3.14 在内存中存储为:0xc3 0xf5 0x48 0x40
注:不同的处理器架构和操作系统可能采用不同的字节序。例如,x86架构的处理器通常采用小端序,而网络协议常使用大端序。因此,在进行跨平台数据交互时,需要注意字节序的转换和处理,以确保数据的正确传输和解析。
整数字节序转换C++代码示例
使用位操作进行转换
我们定义了两个函数 bigEndianToLittleEndian16 和 bigEndianToLittleEndian32,用于将大端序的 16 位整数和 32 位整数转换为小端序。通过位操作和移位运算,我们可以将字节的顺序进行转换。
#include <iostream> #include <cstdint> #include <cstring> // 将一个 16 位整数从大端序转换为小端序 uint16_t bigEndian2LittleEndian16(uint16_t value) {
return (value >> 8) | (value << 8); } // 将一个 32 位整数从大端序转换为小端序 uint32_t bigEndian2LittleEndian32(uint32_t value) {
return ((value & 0xFF000000) >> 24) | ((value & 0x00FF0000) >> 8) | ((value & 0x0000FF00) << 8) | ((value & 0x000000FF) << 24); } int main() {
uint16_t bigEndian16 = 0x1234; uint32_t bigEndian32 = 0x; uint16_t littleEndian16 = bigEndian2LittleEndian16(bigEndian16); uint32_t littleEndian32 = bigEndian2LittleEndian32(bigEndian32); std::cout << "Big Endian 16: 0x" << std::hex << bigEndian16 << std::endl; std::cout << "Little Endian 16: 0x" << std::hex << littleEndian16 << std::endl; std::cout << "Big Endian 32: 0x" << std::hex << bigEndian32 << std::endl; std::cout << "Little Endian 32: 0x" << std::hex << littleEndian32 << std::endl; return 0; }
对应的小端序转为大端序的函数为:
// 将一个 16 位整数从小端序转换为大端序 uint16_t littleEndianToBigEndian16(uint16_t value) {
return (value >> 8) | (value << 8); } // 将一个 32 位整数从小端序转换为大端序 uint32_t littleEndianToBigEndian32(uint32_t value) {
return ((value & 0xFF000000) >> 24) | ((value & 0x00FF0000) >> 8) | ((value & 0x0000FF00) << 8) | ((value & 0x000000FF) << 24); }
使用boost::endian
库进行转换
#include <iostream> #include <boost/endian/conversion.hpp> int main() {
uint16_t bigEndian16 = 0x1234; uint32_t bigEndian32 = 0x; uint16_t littleEndian16 = boost::endian::native_to_little(bigEndian16); uint32_t littleEndian32 = boost::endian::native_to_little(bigEndian32); std::cout << "Big Endian 16: 0x" << std::hex << bigEndian16 << std::endl; std::cout << "Little Endian 16: 0x" << std::hex << littleEndian16 << std::endl; std::cout << "Big Endian 32: 0x" << std::hex << bigEndian32 << std::endl; std::cout << "Little Endian 32: 0x" << std::hex << littleEndian32 << std::endl; return 0; }
对应的小端序转为大端序的示例为:
uint16_t bigEndian16 = boost::endian::native_to_big(littleEndian16); uint32_t bigEndian32 = boost::endian::native_to_big(littleEndian32);
使用Poco::ByteOrder
类进行转换
#include <iostream> #include <Poco/ByteOrder.h> int main() {
uint16_t bigEndian16 = 0x1234; uint32_t bigEndian32 = 0x; uint16_t littleEndian16 = Poco::ByteOrder::flipBytes(bigEndian16); uint32_t littleEndian32 = Poco::ByteOrder::flipBytes(bigEndian32); std::cout << "Big Endian 16: 0x" << std::hex << bigEndian16 << std::endl; std::cout << "Little Endian 16: 0x" << std::hex << littleEndian16 << std::endl; std::cout << "Big Endian 32: 0x" << std::hex << bigEndian32 << std::endl; std::cout << "Little Endian 32: 0x" << std::hex << littleEndian32 << std::endl; return 0; }
对应的小端序转为大端序的示例为:
uint16_t bigEndian16 = Poco::ByteOrder::flipBytes(littleEndian16); uint32_t bigEndian32 = Poco::ByteOrder::flipBytes(littleEndian32);
其他类型字节序转换
对于非整数类型(如字符串、结构体等),字节序的转换需要更加谨慎和具体情况而定。一般情况下,字符串的字节序转换需要考虑字符编码的影响。
如果你需要对字符串进行字节序转换,可以将字符串转换为字节数组,然后对字节数组进行字节序转换,最后再将字节数组转换回字符串。
字符串
#include <iostream> #include <string> #include <vector> #include <algorithm> // 将字符串转换为字节数组std::vector<uint8_t> std::vector<uint8_t> string2Bytes(const std::string& str){
// str.begin() 返回一个迭代器,指向字符串 str 的起始位置,即第一个字符处。 str.end() 返回一个迭代器,指向字符串 str 结束位置的下一个位置,即字符串末尾之后的位置。在 C++ 中,字符串是一种容器,可以使用迭代器来遍历其中的字符。 // 使用了迭代器来遍历字符串中的每个字符,并将每个字符转换为 uint8_t 类型后添加到 std::vector<uint8_t> 容器中。 std::vector<uint8_t> bytes(str.begin(), str.end()); return bytes; } // 将字节数组转换为字符串 std::string bytes2String(const std::vector<uint8_t>& bytes){
std::string str(bytes.begin(), bytes.end()); return str; } // 对字节数组进行字节序转换 void flipBytes(std::vector<uint8_t>& bytes){
std::reverse(bytes.begin(), bytes.end()); } int main() {
std::string str = "Hello, World!"; // 将字符串转换为字节数组 std::vector<uint8_t> bytes = string2Bytes(str); // 对字节数组进行字节序转换 flipBytes(bytes); // 将字节数组转换为字符串 std::string convertedStr = bytes2String(bytes); std::cout << "Original string: " << str << std::endl; std::cout << "Converted string: " << convertedStr << std::endl; return 0; }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/122109.html