📜  c++ little endian or big endian - C++ (1)

📅  最后修改于: 2023-12-03 15:13:54.542000             🧑  作者: Mango

C++中的小端序和大端序

什么是小端序和大端序?

在计算机中,多个字节数据的存储方式有两种:小端序和大端序。在小端序中,低位字节会排在内存的低地址处,而高位字节则排在内存的高地址处;而在大端序中,高位字节会排在内存的低地址处,低位字节则排在内存的高地址处。

例如,对于一个16位数据0x1234,它在小端序中的存储方式为:

低地址 ---------> 高地址
    34     12

而在大端序中的存储方式为:

低地址 ---------> 高地址
    12     34
C++的小端序和大端序

在C++中,小端序和大端序的判断依据是计算机的架构。在x86和x64这样的架构中,通常采用小端序;而在ARM等ARM系列处理器中,则使用大端序。但是,C++并没有规定必须使用哪种字节序。

在进行字节序转换时,可以使用下面的函数:

#include <iostream>
#include <cstdint>
using namespace std;

inline void swap_endian(uint16_t& x) {
    x = (x >> 8) | (x << 8);
}

inline void swap_endian(uint32_t& x) {
    x = (x >> 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x << 24);
}

inline void swap_endian(uint64_t& x) {
    x = (x >> 56) |
        ((x << 40) & 0x00FF000000000000) |
        ((x << 24) & 0x0000FF0000000000) |
        ((x << 8) & 0x000000FF00000000) |
        ((x >> 8) & 0x00000000FF000000) |
        ((x >> 24) & 0x0000000000FF0000) |
        ((x >> 40) & 0x000000000000FF00) |
        (x << 56);
}

int main()
{
    uint16_t x1 = 0x1234;
    uint32_t x2 = 0x12345678;
    uint64_t x3 = 0x123456789abcdef0;

    swap_endian(x1);
    swap_endian(x2);
    swap_endian(x3);

    cout << hex << x1 << endl;
    cout << hex << x2 << endl;
    cout << hex << x3 << endl;
}

这段代码中,定义了三个swap_endian函数,分别处理16位、32位和64位的数据。这里使用了位运算和掩码来进行字节序转换。实际上,除了像上面这样手写转换函数之外,也可以使用系统提供的函数/库进行字节序转换,如htonl、htons、ntohl和ntohs等函数。

总结

小端序和大端序在计算机中的存储方式不同,C++并没有规定必须使用哪种字节序。在进行字节序转换时,可以手写转换函数或使用系统提供的函数/库。了解字节序的概念并能正确处理字节序问题,对编写跨平台代码十分重要。