使用位字场以4位增量访问给定类型的单个位组
Accessing individual bit groups of a given type in 4 bit increments using bit-fields
如何使用位字段以4位增量访问给定的8个字节数据类型?如何在C和C 中编程?
序言,我将向您展示如何在c
中向您展示此虽然您似乎应该只能使用Bitfields来执行此操作,但由于BitFields必须是初始化的元素,因此您不能使用Bitfields。请参阅有关如何在C 中使用Bitfields的更多信息。查看为什么尝试执行以下操作:
struct S{
std::uint32_t x : 16;
std::uint32_t y : 16;
}
// 65536 = 0001 0000 0000 0000 0000 in binary
S s = {65536};
std::cout << s.x << std::endl;
std::cout << s.y << std::endl;
// >>> 0
// >>> 0
// since the first parameter actually only initializes x, and not y.
//you also cannot do the following
S s = 65536 // Error! no conversion between S and uint32_t!
哇,我该如何将基本类型设置为位字段!为了解决这个问题,我们需要使用工会。我将向您展示使用工会解决此问题的最简单答案,然后使用匿名工会和结构链接到更复杂但紧凑的解决方案。
这本质上是您为问题所需要做的:
struct nibble64bitField{
uint64_t A:4;
uint64_t B:4;
uint64_t C:4;
uint64_t D:4;
uint64_t E:4;
uint64_t F:4;
uint64_t G:4;
uint64_t H:4;
uint64_t I:4;
uint64_t J:4;
uint64_t K:4;
uint64_t L:4;
uint64_t M:4;
uint64_t N:4;
uint64_t O:4;
uint64_t P:4;
};
union split8bytes{
std::uint64_t integer;
nibble64bitField bitfield;
};
int main() {
// note this is 255 + 256, or 0000 1111 1111 + 0001 0000 0000
uint64_t eightbyte_value = 511;
split8bytes split = {eightbyte_value};
std::cout << split.bitfield.A << " should be 15" << std::endl;
std::cout << split.bitfield.B << " should be 15" <<std::endl;
std::cout << split.bitfield.C << " should be 1" << std::endl;
std::cout << split.bitfield.D << " should be 0" << std::endl;
std::cout << split.integer << " should be 511" << std::endl;
return 0;
}
在这里您使用工会的使用。现在为什么我们在这里使用工会?工会允许您将给定的工会称为联盟内部的任何成员,但仅占用最大的字节大小成员。这使我们可以将splitbytes
设置为一个整数值,但是从该整数访问单个nibbles(4位或一半字节(。
正如承诺的,另一个用户试图做与您相同的事情,但在代码审核中结束。您的解决方案是手动进行此转换,另一个用户提出使用联合结构范式进行转换(不是相同的问题,不是重复的(。在这里,匿名结构与编译器的布拉格斯一起使用,以确保包装(但仅在某些编译器上(
,因为@snb给了您一个C 解决方案,这是使用数组的C解决方案:
union split8bit_u {
uint8_t byte;
struct {
uint8_t l_nyb:4;
uint8_t u_nyb:4;
};
};
typedef union split8bit_u split8bit;
union split64bit_u {
uint64_t lword;
split8bit byte[8];
};
typedef union split64bit_u split64bit;
int main() {
// note that 0x0123456789ABCDEF
split64bit data;
data.lword = 0x0123456789ABCDEF;
for ( int i = 0; i < sizeof(data); ++i) {
printf("%X.%X.",data.byte[i].l_nyb,data.byte[i].u_nyb);
}
printf("b n");
// Prints "F.E.D.C.B.A.9.8.7.6.5.4.3.2.1.0"
}
这打印出16个离散的4位值。
相关文章:
- 访问者访问变体并返回不同类型时出错
- 通过switch和static_cast访问多态对象的运行时类型
- 访问C++中的类型成员
- 给定一个C++嵌套的私有结构类型,是否有从文件范围静态函数访问它的策略
- 在类 A 中创建类型为 B 类的向量 - 访问数据 [C++] [成员在两个类中都是私有的]
- OpenCV C++:当垫子类型未知时无法访问垫子元素?
- 提供对不同类型的数据(建议、代码审查)的线程安全访问的类
- 通过包装器从 C 访问C++ API 时,如何访问枚举类型
- 用于随机数据访问的最有效文件类型
- reinterpret_cast,只读访问,简单的可复制类型,会出什么问题?
- 我无法在用forward_as_tuple创建的元组中按类型访问元素
- 派生类的访问类型
- 返回对位字段的访问类型
- 在不键入别名类型的完整声明的情况下,无法从类模板定义中访问类型的类型别名
- 在编译时生成和访问类型列表
- 访问类型成员
- 如何在c++中更改继承类型的访问类型
- 使用传入的字符串形参来访问类型中的内容
- Boost::variant获取最后访问类型
- 如何访问类型为class的vector的vector中的value