如何在结构中获取一系列位?
我正在思考(因此,正在寻找一种学习方法的方法,,而不是更好的解决方案),如果可以在结构中获得一系列位。
让我以一个例子进行演示。想象一下这样的代码:
#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("%u\n", a.bit0);
printf("%u\n", a.bit1);
printf("%u\n", a.bit2);
printf("%u\n", a.bit3);
return 0;
}
在此代码中,我们在一个结构中有4个单独的位。可以单独访问它们,将BIT操纵的工作留给编译器。我想知道的是是否有可能:
#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("%u\n", b.bits[i]);
return 0;
}
我尝试在struct> struct b
中声明bits
作为unsigned int Bits [4]:1
或unsigned int位:1 [4]
或类似的东西无济于事。我最好的猜测是typedef unsigned int bit:1;
并使用bit
作为类型,但仍然不起作用。
我的问题是,有可能吗?如果是,怎么样?如果不是,为什么不呢? 1位未签名的INT是有效的类型,那么为什么不应该获得它的数组呢?
同样,我不想为此替代,我只是想知道这样的事情是怎么可能的。
ps我将其标记为C ++,尽管代码是用C编写的,因为我认为该方法在两种语言中都存在。如果有一种C ++特定的方法(通过使用语言构造而不是库),我也很感兴趣。
更新:我完全意识到自己可以自己做点操作。过去,我做过一千次。我对说使用阵列/矢量的答案不感兴趣,并进行了一些操纵。我只是在想是否可以使用此构造,而不是替代方案。
更新:不耐烦的答案(感谢Neagoegab):
而不是
typedef unsigned int bit:1;
我可以使用
typedef struct
{
unsigned int value:1;
} bit;
#pragma pack
来正确使用
I was pondering (and therefore am looking for a way to learn this, and not a better solution) if it is possible to get an array of bits in a structure.
Let me demonstrate by an example. Imagine such a code:
#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("%u\n", a.bit0);
printf("%u\n", a.bit1);
printf("%u\n", a.bit2);
printf("%u\n", a.bit3);
return 0;
}
In this code, we have 4 individual bits packed in a struct. They can be accessed individually, leaving the job of bit manipulation to the compiler. What I was wondering is if such a thing is possible:
#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("%u\n", b.bits[i]);
return 0;
}
I tried declaring bits
in struct B
as unsigned int bits[4]:1
or unsigned int bits:1[4]
or similar things to no avail. My best guess was to typedef unsigned int bit:1;
and use bit
as the type, yet still doesn't work.
My question is, is such a thing possible? If yes, how? If not, why not? The 1 bit unsigned int is a valid type, so why shouldn't you be able to get an array of it?
Again, I don't want a replacement for this, I am just wondering how such a thing is possible.
P.S. I am tagging this as C++, although the code is written in C, because I assume the method would be existent in both languages. If there is a C++ specific way to do it (by using the language constructs, not the libraries) I would also be interested to know.
UPDATE: I am completely aware that I can do the bit operations myself. I have done it a thousand times in the past. I am NOT interested in an answer that says use an array/vector instead and do bit manipulation. I am only thinking if THIS CONSTRUCT is possible or not, NOT an alternative.
Update: Answer for the impatient (thanks to neagoegab):
Instead of
typedef unsigned int bit:1;
I could use
typedef struct
{
unsigned int value:1;
} bit;
properly using #pragma pack
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
不可能 - 这样的构造是不可能的(在这里) - 不可能
一个人可以尝试这样做,但结果是一位存储在一个字节
输出中:
为了从这里访问字节,示例(请注意,Bitfields的布局取决于实现)
NOT POSSIBLE - A construct like that IS NOT possible(here) - NOT POSSIBLE
One could try to do this, but the result will be that one bit is stored in one byte
output:
In order to access individual bits from a byte here is an example (Please note that the layout of the bitfields is implementation dependent)
在 C++ 中,您使用
std::bitset<4>
。这将使用最少数量的单词进行存储,并对您隐藏所有屏蔽。将 C++ 库与该语言分开确实很困难,因为该语言的大部分内容都是在标准库中实现的。在 C 中,没有直接的方法来创建像这样的单个位数组,而是创建一个四位元素或手动进行操作。编辑:
实际上,除了创建结构/类成员的上下文之外,您不能在任何地方使用 1 位无符号类型。在这一点上,它与其他类型非常不同,它不会自动遵循您可以创建它们的数组。
In C++ you use
std::bitset<4>
. This will use a minimal number of words for storage and hide all the masking from you. It's really hard to separate the C++ library from the language because so much of the language is implemented in the standard library. In C there's no direct way to create an array of single bits like this, instead you'd create one element of four bits or do the manipulation manually.EDIT:
Actually you can't use a 1 bit unsigned type anywhere other than the context of creating a struct/class member. At that point it's so different from other types it doesn't automatically follow that you could create an array of them.
C ++将使用
std :: vector&lt; bool&gt;
或std :: bitset&lt; n&gt;
。在C中,要模拟
std :: vector&lt; bool&gt;
语义,您使用类似的结构:其中
Word
是一种实现定义的类型,宽度与数据总线相等CPU;Wordsize
,如稍后使用的,等于数据总线的宽度。例如
word
是uint32_fast_t
32位计算机,uint64_fast_t_t
64位计算机;Wordsize
对于32位计算机为32,64位计算机为64。您使用功能/宏来设置/清除位。
要提取一点,请使用
get_bit(位,位)(((((位位) - &gt;)word [(bit)/wordsize]&amp;(1&lt;&lt;((bit)%wordsize))< /代码>。
要设置一些设置,请使用
set_bit(位,位)((((bits) - &gt;)word [(bit)/wordsize] | =(1&lt;&lt;((bit)%wordsize)))< /代码>。
要清除一点,请使用
clear_bit(位,位)(((((位)) - &gt;)word [(bit)/wordsize]&amp; =〜(1&lt;&lt;((bit)%wordsize)) )
。要翻转一点,请使用
flip_bit(位,位)((((位位) - &gt;)word [(bit)/wordsize] ^=(1&lt;&lt;&lt;((bit)%wordsize))< /代码>。
要添加根据
std :: vector&lt; bool&gt;
添加可重新启动性bits.word_count 相应。这是问题的确切细节。同样适用于正确检查位索引的范围。
C++ would use
std::vector<bool>
orstd::bitset<N>
.In C, to emulate
std::vector<bool>
semantics, you use a struct like this:where
Word
is an implementation-defined type equal in width to the data bus of the CPU;wordsize
, as used later on, is equal to the width of the data bus.E.g.
Word
isuint32_fast_t
for 32-bit machines,uint64_fast_t
for 64-bit machines;wordsize
is 32 for 32-bit machines, and 64 for 64-bit machines.You use functions/macros to set/clear bits.
To extract a bit, use
GET_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] & (1 << ((bit) % wordsize)))
.To set a bit, use
SET_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] |= (1 << ((bit) % wordsize)))
.To clear a bit, use
CLEAR_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] &= ~(1 << ((bit) % wordsize)))
.To flip a bit, use
FLIP_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] ^= (1 << ((bit) % wordsize)))
.To add resizeability as per
std::vector<bool>
, make a resize function which callsrealloc
onBits.word
and changesBits.word_count
accordingly. The exact details of this is left as a problem.The same applies for proper range-checking of bit indices.
这是辱骂性的,并且依靠扩展……但是它对我有用:
this is abusive, and relies on an extension... but it worked for me:
您还可以使用整数(ints或long)数组来构建任意的大掩码。 Select()系统调用将此方法用于其FD_SET类型;每个位对应于编号的文件描述符(0..N)。宏定义:fd_clr有点清除,fd_set设置一些,fd_isset进行测试,而fd_setsize是位总数。宏自动找出要访问的数组中哪个整数以及整数中的位。在UNIX上,请参见“ sys/select.h”;在Windows下,我认为它在“ winsock.h”中。您可以使用FD技术来制作自己的定义。在C ++中,我想您可以创建一个位掩码对象并超载[]运算符以访问单个位。
You can also use an array of integers (ints or longs) to build an arbitrarily large bit mask. The select() system call uses this approach for its fd_set type; each bit corresponds to the numbered file descriptor (0..N). Macros are defined: FD_CLR to clear a bit, FD_SET to set a bit, FD_ISSET to test a bit, and FD_SETSIZE is the total number of bits. The macros automatically figure out which integer in the array to access and which bit in the integer. On Unix, see "sys/select.h"; under Windows, I think it is in "winsock.h". You can use the FD technique to make your own definitions for a bit mask. In C++, I suppose you could create a bit-mask object and overload the [] operator to access individual bits.
您可以使用结构指针创建一些位列表。但是,这将使用每位写的多个空间,因为它将使用一个字节(用于地址):
然后在此之后:
您可以这样访问它们:
You can create a bit list by using a struct pointer. This will use more than a bit of space per bit written though, since it'll use one byte (for an address) per bit:
Then after this:
You can access them like so: