2011-12-19 36 views
53
struct _USBCHECK_FLAGS 
    { 
     unsigned char DEVICE_DEFAULT_STATE  : 1; 
     unsigned char DEVICE_ADDRESS_STATE  : 1; 
     unsigned char DEVICE_CONFIGURATION_STATE : 1; 
     unsigned char DEVICE_INTERFACE_STATE  : 1; 
     unsigned char FOUR_RESERVED_BITS   : 8; 
     unsigned char RESET_BITS     : 8; 
    } State_bits; 

:1:8是什么意思?“:”(结肠)在C结构 - 这是什么意思?

+6

[位域在C](http://en.wikipedia.org/wiki/C_syntax#Bit_fields)。 – birryree 2011-12-19 16:47:30

+0

请参阅http://en.wikipedia.org/wiki/Bit_field – 2011-12-19 16:48:32

+47

“FOUR_RESERVED_BITS:8”... – RJFalconer 2011-12-19 16:53:49

回答

46

那些是位字段。基本上,冒号后面的数字描述该字段使用多少位。这是描述位字段的quote from MSDN

常量表达式指定字段的宽度(以位为单位)。声明的 类型说明符必须是unsigned int,signed int或int,并且常量表达式必须是非负整数值。 如果该值为零,则该声明没有声明。位 字段,位字段指针和返回位字段的函数的数组是 不允许。可选的声明符命名位域。位域 只能声明为结构的一部分。运算符地址 (&)不能应用于位域组件。

未命名的位字段不能被引用,并且它们在运行 时的内容是不可预知的。对于 对齐目的,它们可以用作“虚拟”字段。其宽度被指定为0 的未命名位字段保证在 结构声明列表中的后面的成员的存储在int边界上开始。

本示例定义了一个名为screen的结构的二维数组。

struct 
{ 
    unsigned short icon : 8; 
    unsigned short color : 4; 
    unsigned short underline : 1; 
    unsigned short blink : 1; 
} screen[25][80]; 

编辑:从MSDN链接另一个重要的一点:

位字段具有相同的语义整数类型。这意味着 位字段在表达式中使用的方式与使用相同基本类型的变量 的方式完全相同,无论位字段中有多少位为 。

一个快速示例很好地说明了这一点。有趣的是,对于混合类型,编译器似乎默认为sizeof (int)

struct 
    { 
    int a : 4; 
    int b : 13; 
    int c : 1; 
    } test1; 

    struct 
    { 
    short a : 4; 
    short b : 3; 
    } test2; 

    struct 
    { 
    char a : 4; 
    char b : 3; 
    } test3; 

    struct 
    { 
    char a : 4; 
    short b : 3; 
    } test4; 

    printf("test1: %d\ntest2: %d\ntest3: %d\ntest4: %d\n", sizeof(test1), sizeof(test2), sizeof(test3), sizeof(test4)); 

测试1:4

测试2:2

TEST3:1

TEST4:4

+0

链接已过时,请更新。 – zhangxaochen 2015-10-11 12:47:29

+0

更新为新的MSDN链接和文本,以防链接消失。 – JoeFish 2015-10-13 20:41:47

+0

我还是不明白。这是否意味着C++会自动将您的“变量”合并到int大小中,以便使用所有位?你可以将位域structiores转换为数字来获得典型的“* int with flags *”。 – 2015-11-30 09:04:24

6

它定义的宽度为1位字段和8

+19

虽然准确,但答案应解释什么是位域_is_。 – 2011-12-19 17:48:45

4

我也跑进了冒号符号,但在我的上下文位字段没有意义。所以我做了一些挖掘。这个符号也用于分配值 - 在我的具体情况指针函数。

来源:http://www.tldp.org/LDP/lkmpg/2.4/html/c577.htm

下面是一个示例,并摘录来解释。

有没有使人分配给这个结构更方便 gcc的一个扩展。你会看到它在现代的驱动程序,可以出其不意抓住你,这就是分配给结构看起来像的新方法:”

​​

的C99(旧,兼容)的方式是这样的:

struct file_operations fops = { 
    .read = device_read, 
    .write = device_write, 
    .open = device_open, 
    .release = device_release 
}; 
+0

我也看到了这个!我一直认为gcc扩展名是'.x = y',标准采用了它,直到后来我看到'x:y'符号。我相信标准的一个看起来更好。 – Shahbaz 2013-10-30 18:36:38

+6

首先,这不是赋值,它是*初始化*。其次,你描述的特征(*指定的初始化符*)与问题的关键(*位域*)完全无关。仅仅因为过时的GCC扩展在语法中使用了':'并不意味着它与问题中的':'有任何关系。 – AnT 2013-10-30 18:37:09

+4

AnT,搜索“C结构体初始化冒号”的人可能会找到这个答案,这正是我正在寻找的。谢谢,user27346! – ChrisPhoenix 2015-11-27 21:02:32