标签: bit-fields

可以在C++类中使用位字段吗?

在C结构中,可以指定另一个位长度,而不是类型的默认位长度,如下所示:

struct MyStruct{
    int myVar : 1;    //Size of myVar is 1 bit (so it can take values 0 or 1
    int myOtherVar: 4;    //Size of myOtherVar is 4 bits (so it can take values 0 to 15)
}
Run Code Online (Sandbox Code Playgroud)

这称为位字段.

我的问题是,是否也可以在C++类中执行此操作,如下所示:

class MyClass{
    public:
        //Some methods
    private:
        int m_myAttribute : 1;
        int m_myOtherAttribute : 4;
}
Run Code Online (Sandbox Code Playgroud)

我在网上搜索了这个,但我找到的所有比特字段的例子都使用了结构,而不是类.

我测试了这段代码并且编译得很好,但是我想知道属性的大小是否真的是指定的大小,或者编译器是否忽略了位字段并使用了标准int大小.

c++ class bit-fields

9
推荐指数
1
解决办法
3120
查看次数

关于C位域的问题

  • bitfield是C概念还是C++?

  • 它只能在结构中使用吗?我们可以使用它们的其他地方是什么?

  • AFAIK,bitfields是特殊的结构变量,只占用指定的no.比特.它有助于节省内存而不是其他任何东西.我对么?

我编写了一个小程序来理解位域的使用 - 但是,我认为它没有按预期工作.我希望下面结构的大小为1 + 4 + 2 = 7个字节(考虑到unsigned int的大小在我的机器上是4个字节),但令我惊讶的是,结果是12个字节(4 + 4 + 4) ).谁能让我知道为什么?

#include <stdio.h>

struct s{
unsigned int a:1;
unsigned int b;
unsigned int c:2;
};

int main()
{
  printf("sizeof struct s = %d bytes \n",sizeof(struct s));
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

OUTPUT:

sizeof struct s = 12 bytes 
Run Code Online (Sandbox Code Playgroud)

c bit-fields

8
推荐指数
2
解决办法
1296
查看次数

Go:Bitfields和bit packing

C语言的位域提供了一种在结构中定义任意宽度字段的相当方便的方法(永远不要在一分钟内解决可移植性问题.)例如,这是一个带有几个字段和'flag'的简单结构:

#pragma pack(push,1)
struct my_chunk{

    unsigned short fieldA: 16;
    unsigned short fieldB: 15;
    unsigned short fieldC:  1;
};
#pragma pop()
Run Code Online (Sandbox Code Playgroud)

添加#pragma语句将此结构打包成一个32位字(确保指针的指针操作my_chunk对齐,例如,节省空间).

访问每个字段在语法上非常好:

struct my_chunk aChunk;
aChunk.fieldA = 3;
aChunk.fieldB = 2;
aChunk.fieldC = 1;
Run Code Online (Sandbox Code Playgroud)

在没有语言帮助的情况下执行此操作的替代方法相当丑陋,并且几乎可以转换为汇编程序.例如,一种解决方案是为要访问的每个字段设置bitshift宏:

#define FIELD_A  0xFF00
#define FIELD_B  0x00FE
#define FIELD_C  0x0001

#define get_field(p, f) ((*p)&f)
#define set_field(p, f, v) (*p) = (v<<f) + (*p)&(~f)

...
set_field(&my_chunk, FIELD_A, 12345);
Run Code Online (Sandbox Code Playgroud)

..或类似的东西(为了更正式,看看这个)

所以问题是,如果我想在go中"做"bitfields,这样做的最佳做法是什么?

go bit-fields

8
推荐指数
2
解决办法
6002
查看次数

如何使用LINQ和lambdas对列表中对象的位标志枚举属性执行按位OR?

我有一个对象集合,每个对象都有一个位字段枚举属性.我想要得到的是整个集合中位字段属性的逻辑OR.如何通过循环遍历集合(希望使用LINQ和lambda)来完成此操作?

这是我的意思的一个例子:

[Flags]
enum Attributes{ empty = 0, attrA = 1, attrB = 2, attrC = 4, attrD = 8}

class Foo {
    Attributes MyAttributes { get; set; }
}

class Baz {
    List<Foo> MyFoos { get; set; }

    Attributes getAttributesOfMyFoos() {
        return // What goes here? 
    }
}
Run Code Online (Sandbox Code Playgroud)

我试过这样用.Aggregate:

return MyFoos.Aggregate<Foo>((runningAttributes, nextAttributes) => 
    runningAttributes | nextAttribute);
Run Code Online (Sandbox Code Playgroud)

但这不起作用,我无法弄清楚如何使用它来得到我想要的东西.有没有办法使用LINQ和一个简单的lambda表达式来计算这个,或者我只是在集合上使用循环?

注意:是的,这个示例案例很简单,基本foreach将是要走的路,因为它简单且不复杂,但这只是我实际使用的简化版本.

c# lambda enums aggregate bit-fields

8
推荐指数
1
解决办法
4559
查看次数

如何使用位字段为结构赋值?

我有一个带有位字段的结构(总共32位宽度),我有一个32位变量.当我尝试将变量值分配给我的结构时,我收到一个错误:

错误:从'uint32_t {aka unsigned int}'转换为请求的非标量类型'main():: CPUID'.

struct CPUIDregs
    {
       uint32_t EAXBuf;
    };
CPUIDregs CPUIDregsoutput;   


int main () {

 struct CPUID          
    {
          uint32_t   Stepping         : 4;         
          uint32_t   Model            : 4;        
          uint32_t   FamilyID         : 4;        
          uint32_t   Type             : 2;        
          uint32_t   Reserved1        : 2;         
          uint32_t   ExtendedModel    : 4;         
          uint32_t   ExtendedFamilyID : 8;          
          uint32_t   Reserved2        : 4;          
    };

    CPUID CPUIDoutput = CPUIDregsoutput.EAXBuf;
Run Code Online (Sandbox Code Playgroud)

你知道如何以最短的方式做到这一点吗?谢谢

PS当然我在实际代码中有更合适的EAX值,但我想这不会影响到这里.

c++ bit-fields

8
推荐指数
2
解决办法
1万
查看次数

C中的Bit_fields数组

我在C中有一个8位的标志,我想使用这样的位字段逐位访问它:

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

int main(void) {
    struct flags{
        uint8_t bits1:1;
        uint8_t bits2:1;
        uint8_t bits3:1;
        uint8_t bits4:1;
        uint8_t bits5:1;
        uint8_t bits6:1;
        uint8_t bits7:1;
        uint8_t bits8:1;
    };
    struct flags *my_flags;
    uint8_t x=6,i;

    my_flags=(struct flags *)&x;
    printf("%u\t",my_flags->bits5);
    printf("%u\t",my_flags->bits6);
    printf("%u\t",my_flags->bits7);
    printf("%u\t",my_flags->bits8);
    printf("%u\t",my_flags->bits1);
    printf("%u\t",my_flags->bits2);
    printf("%u\t",my_flags->bits3);
    printf("%u\t",my_flags->bits4);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到了预期的输出:0 0 0 0 0 1 1 0.

但这有点太多编码.

  1. 是不是像位字段数组或任何其他解决方法?(要么)
  2. 在C my_flags->bits_i中有什么类似的东西,i它将成为循环中的计数器吗?

我知道默认情况下两者都不存在.但有没有其他方法可以实现相同的目标?

c bit-fields

8
推荐指数
2
解决办法
1544
查看次数

为什么打包结构5的大小而不是4个字节?

参见在线示例: Ideone示例

struct {
  union {
    struct {
      uint32_t messageID : 26;
      uint8_t priority : 3; 
    } __attribute__ ((packed));
    uint32_t rawID : 29;
  } __attribute__ ((packed));
  uint8_t canFlags : 3;
} __attribute__ ((packed)) idSpecial;
Run Code Online (Sandbox Code Playgroud)

为什么编译器会将结构的大小报告为5个字节而不是4个?它应该包含32位.

c c++ gcc struct bit-fields

8
推荐指数
2
解决办法
1103
查看次数

C - Eratosthenes的筛子 - BitField

我即将实施Eratosthenes筛,并对筛阵有一个普遍的问题.

我现在已经实施了几次筛子(在C中),并且总是使用一组uint8_t(外<stdint.h>)作为筛子.这是非常低效的内存,因为每个数字都使用8位来筛选,即使一位应该足够.

我怎么会用C来解决这个问题呢?我需要一个位数组.我可以几乎创建任何类型的(阵列uint8_t,uint16_t,uint32_t,uint64_t),并与比特掩码等访问单个位

我应该选择哪种数据类型以及在没有性能损失的情况下应该使用哪些操作来访问这些位?

PS:我不认为这是一个重复的只是一个BitArray实现,因为它的问题是具体的关于埃拉托色尼的筛,因为它的主要性质必须是有效的(不仅在内存使用情况,但在访问).我在想,也许可以使用不同的技巧来使筛分过程更有效...

c arrays sieve sieve-of-eratosthenes bit-fields

8
推荐指数
1
解决办法
236
查看次数

是否可以在 GCC/GNU C 中编写一个 _Static_assert 来验证编译时内存中位字段的布局?

假设我有以下定义:

#include <stdbool.h>
#include <stdint.h>
#define ASSERT(cond) _Static_assert(cond, #cond)

typedef union {
    struct {
        bool bit0:1;
        bool bit1:1;
        bool bit2:1;
        bool bit3:1;
        bool bit4:1;
        bool bit5:1;
        bool bit6:1;
        bool bit7:1;
    };
    uint8_t bits;
} byte;

ASSERT(sizeof(byte) == sizeof(uint8_t));
Run Code Online (Sandbox Code Playgroud)

能不能写个代码,比如

#include <assert.h>
// ...
    assert(((byte) { .bit0 = 1 }).bits == 0b00000001);
    assert(((byte) { .bit1 = 1 }).bits == 0b00000010);
    assert(((byte) { .bit2 = 1 }).bits == 0b00000100);
    assert(((byte) { .bit3 = 1 }).bits == 0b00001000);
    assert(((byte) { .bit4 = 1 …
Run Code Online (Sandbox Code Playgroud)

c gcc static-assert assertion bit-fields

8
推荐指数
1
解决办法
291
查看次数

C++ 合并位域吗?

只是出于好奇,如果我有一个带有位字段的结构

struct Foo
{
    char a : 1;
    char b : 1;
    char c : 1;
}
Run Code Online (Sandbox Code Playgroud)

另一个带有位域和 struct Foo 的结构

struct Bar
{
    Foo foo;

    char a : 1;
    char b : 1;
    char c : 1;
}
Run Code Online (Sandbox Code Playgroud)

所有这些位都会被打包成一个整数吗?

在这种情况下,这些字段是否会被重新排序以形成单个位字段?

struct Baz
{
    char a : 1;

    int NotBitfield;

    char b : 1;
    char c : 1;
}
Run Code Online (Sandbox Code Playgroud)

c++ bit-fields

8
推荐指数
1
解决办法
184
查看次数