diff --git a/代码/大端小端.md b/代码/大端小端.md index 1219e7a..3dabc43 100644 --- a/代码/大端小端.md +++ b/代码/大端小端.md @@ -20,5 +20,44 @@ created: 2022-01-14 00:12:17Z 0xABCDEF在内存中即为0xEF|0xCD|0xAB # 场景 x86等多是小端 -ARM等为可配置 +ARM等为可配置,一般默认为小端 + +# 判断、转换 +```c +// 判断系统大端序还是小端序 + +static uint8_t IsBigEndian() { +    uint32_t num = 0x12345678; +    return ((*(uint8_t*)&num) == 0x12); +} + +// 将数据按大端序填充 + +static void FillBigEndian32(uint8_t *data,  uint32_t value) { +    if(!IsBigEndian()) { +        for(uint16_t i = 0; i < 4; i++) { +            data[i] = (value >> ((4 - i - 1) * 8)) & 0xFF; +        } +    } +    else { +        for(uint16_t i = 0; i < 4; i++) { +            data[i] = (value >> (i * 8)) & 0xFF; +        } +    } +} + +static void FillBigEndian16(uint8_t *data, uint16_t value) { +    if(!IsBigEndian()) { +        for(uint16_t i = 0; i < 2; i++) { +            data[i] = (value >> ((2 - i - 1) * 8)) & 0xFF; +        } +    } + +    else { +        for(uint16_t i = 0; i < 2; i++) { +            data[i] = (value >> (i * 8)) & 0xFF; +        } +    } +} +``` diff --git a/代码/结构体.md b/代码/结构体.md new file mode 100644 index 0000000..d841329 --- /dev/null +++ b/代码/结构体.md @@ -0,0 +1,32 @@ +--- +tags: + - 字节对齐 + - 代码块 + - 结构体大小 +--- +# sizeof +一般情况下,sizeof 的结果是在编译时确定的,这与结构体的成员类型和对齐规则密切相关。 +## 1. 结构体含有指针成员 +当结构体包含指针成员时,sizeof 返回的是指针本身的大小,而不是指针所指向的数据的大小。指针的大小取决于目标平台的架构,通常在 32 位系统上为 4 字节,在 64 位系统上为 8 字节。 +## 2. 结构体含有柔性数组成员(Flexible Array Member) +柔性数组成员是一个特殊的数组,它只能作为结构体的最后一个成员,并且在结构体定义时,其大小是未知的,声明方式是 type array_name[];或 type array_name[0];。 使用sizeof获取柔性数组所在的结构体大小时,不会包含柔性数组的大小。 柔性数组的大小需要通过动态分配内存来确定。 +# 字节对齐 +在某些情况下,编译器可能会为了提高内存访问效率而进行内存对齐。如果发生了内存对齐,结构体的大小可能会比简单累加成员大小的结果要大。 +## 强制对齐 +使用`#pragma pack N`可强制对齐。若要获取结构体的真实大小,需要`#pragma pack 1`. +对于不敏感的结构体,可采用默认对齐方式。 +若只想某个结构体强制对齐,使用如下方式包裹结构体: +```c +#pragma pack(push, 1) // 设置对齐为1字节 +typedef struct { + uint8_t sensorStatus; // 下挂设备状态 + ValveStatus_t valves; // 两个三通阀状态 + PumpStatus_t pumps; // 两个泵状态 + uint8_t bubbleStatus; // 气泡状态 + float activityMeter; // 活度计uCi + uint8_t estopStatus; // 急停状态 + uint8_t errorCode; // 错误码 + uint8_t initStatus; // 初始化状态 +} DeviceStatus_t; +#pragma pack(pop) // 恢复默认对齐 +``` \ No newline at end of file