gpt4 book ai didi

c : 4x14bit + 1x8bit within a 64 bit 'container' 中的自定义数据类型

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:56:48 26 4
gpt4 key购买 nike

我目前正在尝试找出一种优雅且方便的方法来在 64 位边界内存储 4 个 14 位值和 1 个 8 位值。

像这样:

typedef struct my64bit{
unsigned data1 : 14;
unsigned data2 : 14;
unsigned data3 : 14;
unsigned data4 : 14;
unsigned other : 8;
}tmy64Bit;

稍后我不想创建这些“容器”的数组

tmy64Bit myArray[1000];

所以我有一个指向 1000x64 位内存的指针“myArray”

这个数组通过 tcp 发送到一个嵌入式 linux SOCFPGA 系统,在那里它应该被复制(纠正字节顺序和网络字节顺序)到一个特定的内存(直接从 fpga 访问)

我的问题是上面的代码没有创建 64 位类型

sizeof(tmy64Bit)

返回 12,所以分配了 12 个字节而不是 8 个

用数据填充结构并观察内存(在我的 64 位 linux 系统上)返回这个

tmy64Bit test;
memset(&test,0,sizeof(tmy64Bit));
test.data1 = 0x3fff;
...
test.other = 0xAA;

Memory View:
after d1 written = 0xFF3F0000 00000000 00000000
after d2 written = 0xFFFFFF0F 00000000 00000000
after d3 written = 0xFFFFFF0F FF3F0000 00000000
after d4 written = 0xFFFFFF0F FFFFFF0F 00000000
after o written = 0xFFFFFF0F FFFFFF0F AA000000

因此前 2 个 14 位变量被正确存储,但随后填充填充了最后一个半字节,最后最后一个字节需要存储在一个新的 64 位单元中

另一种方法是

typedef struct my2nd64Bit{
uint8_t data[7];
uint8_t other;
}tmy2nd64Bit;

哪里有

sizeof(tmy2nd64Bit)

返回 8(这是预期的)

这会生成正确的填充结构,但是存储 14 位总是涉及大量的位移和屏蔽

最佳答案

避免使用位字段,它们在 C 标准中的定义很差,几乎无法在实践中使用。您的位域结构代码包含大约 5 到 10 种不同形式的不明确行为。 C 标准位域是一个危险且多余的特性,就这么简单。

相反,只需使用二进制值的原始数组,如下所示:

typedef union {
uint8_t array [sizeof(uint64_t)];
uint64_t val64;
}tmy64Bit;

(请注意 union 中的 uint64_t 将依赖字节顺序)

在这种原始数组中设置和清除位的实际方法是:

void set_bit (tmy64Bit* x, size_t bit)
{
x->array [bit / 8] |= 1 << (bit % 8);
}

void clear_bit (tmy64Bit* x, size_t bit)
{
x->array [bit / 8] &= ~(1 << (bit % 8));
}

或者,如果你愿意,一个更具可读性的版本(等效):

void set_bit (tmy64Bit* x, size_t bit)
{
uint8_t byte_index = bit / 8;
uint8_t bit_index = bit % 8;

x->array[byte_index] |= 1 << bit_index;
}

关于c : 4x14bit + 1x8bit within a 64 bit 'container' 中的自定义数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35724387/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com