在计算机中,字节序指的是多字节数据的存储顺序。最常见的字节序有两种:大端字节序(Big-Endian)和小端字节序(Little-Endian)。
大端字节序是指最高有效位(Most Significant Bit,简称MSB)保存在内存的低地址中,而最低有效位(Least Significant Bit,简称LSB)保存在内存的高地址中。小端字节序则相反,LSB保存在内存的低地址中,而MSB保存在内存的高地址中。
在进行网络通信或跨平台数据交换时,需要确保数据的一致性,因此需要判别或转换字节序。
在C++语言中,可以通过以下方法判别或转换字节序:
判别字节序
可以使用如下代码判别当前系统的字节序:
#include <iostream>
void checkEndian() {
int num = 1;
if (*(char *)&num == 1) {
std::cout << "Little-Endian" << std::endl;
} else {
std::cout << "Big-Endian" << std::endl;
}
}
void checkEndian1(){
int x = 0x1234;
if(*(char*)&x == 0x12){
std::cout << "Big-Endian" << std::endl;
}else{
std::cout << "Little-Endian" << std::endl;
}
}
该代码将整数1的地址强制转换为字符指针,如果LSB为1,则说明当前系统是小端字节序,否则为大端字节序。
转换字节序
对于多字节数据,可以使用以下方法进行字节序转换:
#include <iostream>
#include <cstring>
int convertEndian() {
unsigned int num = 0x12345678; // 32位整数,假设为大端字节序
unsigned char bytes[4];
memcpy(bytes, &num, sizeof(num)); // 将num的字节拷贝到bytes数组中
if (bytes[0] == 0x12 && bytes[1] == 0x34 && bytes[2] == 0x56 && bytes[3] == 0x78) {
std::cout << "Big-Endian" << std::endl;
unsigned int converted_num = (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0]; // 转换为大端字节序
std::cout << "Converted: " << std::hex << converted_num << std::endl;
} else {
std::cout << "Little-Endian" << std::endl;
unsigned int converted_num = (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]; // 转换为小端字节序
std::cout << "Converted: " << std::hex << converted_num << std::endl;
}
return 0;
}
int convertEndian1(){
unsigned int num = 0x12345678;
unsigned int dst = (num&0xff) << 24|
(num&0xff00) << 8|
(num&0xff0000) >> 8|
(num&0xff000000) >> 24;
std::cout << "Origin:" << std::hex << num << " "
<< "Converted:" << std::hex << dst << " "
<< "htonl:" << std::hex << htonl(num) << std::endl;
return 0;
}
该代码将整数0x12345678的字节拷贝到一个字符数组中,然后根据字节序的不同进行转换。对于大端字节序,最高有效字节保存在数组的第一个元素中,因此按照顺序进行转换即可;对于小端字节序,最低有效字节保存在数组的第一个元素中,需要倒序进行转换。