如何在结构中获得位数组
How to get array of bits in a structure?
我正在思考(因此我正在寻找一种学习这一点的方法,而不是更好的解决方案),如果有可能在结构中获得位数组。
让我用一个例子来说明。想象这样一个代码:
#include <stdio.h>
struct A
{
unsigned int bit0:1;
unsigned int bit1:1;
unsigned int bit2:1;
unsigned int bit3:1;
};
int main()
{
struct A a = {1, 0, 1, 1};
printf("%un", a.bit0);
printf("%un", a.bit1);
printf("%un", a.bit2);
printf("%un", a.bit3);
return 0;
}
在这段代码中,我们在一个结构体中封装了4个单独的位。它们可以单独访问,将位操作的工作留给编译器。我想知道这样的事情是否可能:
#include <stdio.h>
typedef unsigned int bit:1;
struct B
{
bit bits[4];
};
int main()
{
struct B b = {{1, 0, 1, 1}};
for (i = 0; i < 4; ++i)
printf("%un", b.bits[i]);
return 0;
}
我试图在struct B
中声明bits
为unsigned int bits[4]:1
或unsigned int bits:1[4]
或类似的东西,但无济于事。我最好的猜测是typedef unsigned int bit:1;
和使用bit
作为类型,但仍然不起作用。
我的问题是,这样的事情可能吗?如果是,怎么做?如果不是,为什么不呢?1位unsigned int是一种有效类型,所以为什么不能得到它的一个数组呢?
再说一遍,我不想要一个替代品,我只是想知道这样的事情是怎么可能的。
注:虽然代码是用C编写的,但我将其标记为c++,因为我假设该方法在两种语言中都存在。如果有一种c++特有的方法(通过使用语言结构,而不是库),我也很想知道。
更新:我完全知道我可以自己做位操作。我以前做过上千次了。我对一个回答不感兴趣,说使用数组/向量,而不是做位操作。
我只是在想这个CONSTRUCT是否可行,而不是另一种选择。更新:给没有耐心的人的答案(感谢neagoegab):
不是typedef unsigned int bit:1;
我可以用
typedef struct
{
unsigned int value:1;
} bit;
正确使用#pragma pack
NOT POSSIBLE - 这样的构造是不可能的(这里) - NOT POSSIBLE
可以尝试这样做,但结果将是一个比特存储在一个字节
#include <cstdint>
#include <iostream>
using namespace std;
#pragma pack(push, 1)
struct Bit
{
//one bit is stored in one BYTE
uint8_t a_:1;
};
#pragma pack(pop, 1)
typedef Bit bit;
struct B
{
bit bits[4];
};
int main()
{
struct B b = {{0, 0, 1, 1}};
for (int i = 0; i < 4; ++i)
cout << b.bits[i] <<endl;
cout<< sizeof(Bit) << endl;
cout<< sizeof(B) << endl;
return 0;
}
输出:0 //bit[0] value
0 //bit[1] value
1 //bit[2] value
1 //bit[3] value
1 //sizeof(Bit), **one bit is stored in one byte!!!**
4 //sizeof(B), ** 4 bytes, each bit is stored in one BYTE**
为了从字节中访问单个位,这里有一个示例(请注意,位域的布局取决于实现)
#include <iostream>
#include <cstdint>
using namespace std;
#pragma pack(push, 1)
struct Byte
{
Byte(uint8_t value):
_value(value)
{
}
union
{
uint8_t _value;
struct {
uint8_t _bit0:1;
uint8_t _bit1:1;
uint8_t _bit2:1;
uint8_t _bit3:1;
uint8_t _bit4:1;
uint8_t _bit5:1;
uint8_t _bit6:1;
uint8_t _bit7:1;
};
};
};
#pragma pack(pop, 1)
int main()
{
Byte myByte(8);
cout << "Bit 0: " << (int)myByte._bit0 <<endl;
cout << "Bit 1: " << (int)myByte._bit1 <<endl;
cout << "Bit 2: " << (int)myByte._bit2 <<endl;
cout << "Bit 3: " << (int)myByte._bit3 <<endl;
cout << "Bit 4: " << (int)myByte._bit4 <<endl;
cout << "Bit 5: " << (int)myByte._bit5 <<endl;
cout << "Bit 6: " << (int)myByte._bit6 <<endl;
cout << "Bit 7: " << (int)myByte._bit7 <<endl;
if(myByte._bit3)
{
cout << "Bit 3 is on" << endl;
}
}
在c++中使用std::bitset<4>
。这将使用最小数量的单词进行存储,并对您隐藏所有屏蔽。很难将c++库与c++语言分开,因为c++语言的很多功能都是在标准库中实现的。在C语言中,没有像这样直接创建单个位数组的方法,相反,您可以创建一个四位元素或手动操作。
1位unsigned int是一个有效的类型,所以为什么不能呢得到它的数组?
实际上,除了创建结构/类成员的上下文中,您不能在任何地方使用1位unsigned类型。在这一点上,它与其他类型是如此的不同,以至于你不能自动创建一个数组
c++将使用std::vector<bool>
或std::bitset<N>
。
在C语言中,为了模拟std::vector<bool>
语义,您可以使用这样的结构体:
struct Bits {
Word word[];
size_t word_count;
};
其中Word
是一个与CPU数据总线宽度相等的实现定义类型;后面使用的wordsize
等于数据总线的宽度。
。32位机器的Word
是uint32_fast_t
, 64位机器的uint64_fast_t
;wordsize
在32位机器上是32,在64位机器上是64。
使用函数/宏来设置/清除位。
使用GET_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] & (1 << ((bit) % wordsize)))
提取位。
使用SET_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] |= (1 << ((bit) % wordsize)))
设置位。
清除位,使用CLEAR_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] &= ~(1 << ((bit) % wordsize)))
。
翻转位,使用FLIP_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] ^= (1 << ((bit) % wordsize)))
。
要根据std::vector<bool>
添加可调整大小,请创建一个resize函数,该函数在Bits.word
上调用realloc
并相应地更改Bits.word_count
。具体细节留作留待解决。
同样适用于位索引的正确范围检查。
这是滥用,并依赖于扩展…但它对我有效:
struct __attribute__ ((__packed__)) A
{
unsigned int bit0:1;
unsigned int bit1:1;
unsigned int bit2:1;
unsigned int bit3:1;
};
union U
{
struct A structVal;
int intVal;
};
int main()
{
struct A a = {1, 0, 1, 1};
union U u;
u.structVal = a;
for (int i =0 ; i<4; i++)
{
int mask = 1 << i;
printf("%dn", (u.intVal & mask) >> i);
}
return 0;
}
您还可以使用整数(整型或长型)数组来构建任意大的位掩码。select()系统调用对其fd_set类型使用这种方法;每个位对应编号的文件描述符(0..N)。宏的定义是:FD_CLR用于清除一个位,FD_SET用于设置一个位,FD_ISSET用于测试一个位,FD_SETSIZE是位的总数。宏自动计算出要访问数组中的哪个整数以及整数中的哪位。在Unix上,参见"sys/select.h";在Windows下,我认为它在"winsock.h"中。您可以使用FD技术为位掩码创建自己的定义。在c++中,我认为您可以创建一个位掩码对象并重载[]操作符来访问单个位。
可以使用struct指针创建位列表。但是,这样每写一个比特就会使用更多的空间,因为它每写一个比特就会使用一个字节(用于地址):
struct bitfield{
unsigned int bit : 1;
};
struct bitfield *bitstream;
之后:
bitstream=malloc( sizeof(struct bitfield) * numberofbitswewant );
你可以这样访问它们:
bitstream[bitpointer].bit=...
- 从函数中全局删除并重新实例化数组结构,而无需在编译时知道数组的大小
- 如何使用函数的输出初始化 const 数组结构字段?
- 传递数组结构、ofstream 和 interger 以运行
- 从文本文件中读取并输入到数组结构中,然后显示读取的数据C++
- 将文本文件读取到数组结构中
- C/C++中数组结构和数组结构的通用接口
- C++ MDC final-在字符类型的数组结构中按字母顺序对记录中的名称进行排序
- C++ 使用数组结构创建平衡的二叉搜索树
- C++:释放动态数组(结构成员)和指向此结构的指针的方法
- 使用 vector 在 c++ 中声明 3D 数组结构
- 数组结构无法正确打印
- 如何在C++中访问数组结构内部的数组结构
- CIN进入数组结构似乎什么也没输入
- ifstream将数组结构到txt文件中,然后尽可能将其提取为数组
- wlanapi-将WlanFreeMemory释放其WLAN_INTERFACE_INFO数组结构
- 显示数组结构 c++
- C++ 使用函数访问数组结构的方法是什么?
- 将庞大的数组结构复制到 GPU
- 如何封送包含字符矩阵的数组结构
- C++多维数组结构的对齐