You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将任意位宽(如5位)元素无填充打包到unsigned char数组中

无填充任意位宽元素写入unsigned char数组方案

实现逻辑

要实现任意位宽元素无填充写入uint8_t数组,核心是拆分写入位置的字节偏移和位偏移,逐字节处理跨字节的写入需求:

  • 计算当前待写入元素的全局起始位位置,拆分得到对应的数组字节索引、当前字节内的起始位偏移
  • 优先占用当前字节剩余的空闲位,剩余的待写入位自动顺延到下一个字节处理,循环直到所有位写入完成
  • 全程操作uint8_t类型指针,没有位宽上限,不存在宽指针延后问题

完整可运行代码

#include <stdio.h>
#include <stdint.h>
#include <string.h>

# define VALUE_1_SIZE_BITS      2
# define VALUE_2_SIZE_BITS      3
// 单个元素总占位数
# define ELEM_TOTAL_BITS        (VALUE_1_SIZE_BITS + VALUE_2_SIZE_BITS)
# define FREE_BYTES             5

struct delta_measurement_struct {
    unsigned delta_time: VALUE_1_SIZE_BITS;
    unsigned delta_sensor_data: VALUE_2_SIZE_BITS;
} __attribute__((packed));  // 避免结构填充

void data_struct_array_set(uint8_t *t, unsigned idx, struct delta_measurement_struct delta_measurement) {
    // 合并元素值,先做位掩码过滤,避免无效高位污染数据
    const unsigned v = ((delta_measurement.delta_time & ((1U << VALUE_1_SIZE_BITS) - 1)) << VALUE_2_SIZE_BITS) 
                        | (delta_measurement.delta_sensor_data & ((1U << VALUE_2_SIZE_BITS) - 1));
    unsigned remaining_bits = ELEM_TOTAL_BITS;
    unsigned current_val = v;
    // 计算写入起始位置
    unsigned start_bit = ELEM_TOTAL_BITS * idx;
    unsigned byte_idx = start_bit / 8;
    unsigned bit_in_byte = start_bit % 8;

    while (remaining_bits > 0) {
        // 当前字节剩余可写入位数
        unsigned curr_avail = 8 - bit_in_byte;
        // 本次实际写入位数
        unsigned write_cnt = remaining_bits < curr_avail ? remaining_bits : curr_avail;
        unsigned write_mask = (1U << write_cnt) - 1;
        // 写入当前字节
        t[byte_idx] |= (current_val & write_mask) << bit_in_byte;
        // 更新状态变量
        current_val >>= write_cnt;
        remaining_bits -= write_cnt;
        byte_idx++;
        bit_in_byte = 0;
    }
}

int main() {
    uint8_t delta_measurements[FREE_BYTES];

    memset(delta_measurements, 0, sizeof(delta_measurements));
    // 计算可写入的元素总数
    unsigned max_elems = (FREE_BYTES * 8) / ELEM_TOTAL_BITS;
    for (int i = 0; i < max_elems; ++i) {
        printf("写入第%d个元素,占%d位\n", i+1, ELEM_TOTAL_BITS);
        data_struct_array_set(delta_measurements, i, (struct delta_measurement_struct) {3, 7});

        printf("数组当前值:0x");
        for (int j = 0; j < FREE_BYTES; ++j) {
            printf("%02X-", delta_measurements[j]);
        }
        printf("\n");
    }

    return 0;
}

使用说明

你可以根据需求修改VALUE_1_SIZE_BITS、VALUE_2_SIZE_BITS调整单元素的位宽,修改FREE_BYTES调整存储数组的大小,代码会自动处理跨字节写入的逻辑,不需要手动调整字节索引。


内容的提问来源于stack exchange,提问作者HennyKo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 02:06:06