C结构中的“:”(冒号) - 这是啥意思? [复制]

Posted

技术标签:

【中文标题】C结构中的“:”(冒号) - 这是啥意思? [复制]【英文标题】:":" (colon) in C struct - what does it mean? [duplicate]C结构中的“:”(冒号) - 这是什么意思? [复制] 【发布时间】:2011-12-19 16:45:10 【问题描述】:
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 是什么意思?

【问题讨论】:

Bitfields in C. 参见en.wikipedia.org/wiki/Bit_field 示例 "FOUR_RESERVED_BITS : 8" ... 【参考方案1】:

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

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

无法引用未命名的位域,并且它们的内容在运行时 时间是不可预测的。它们可以用作“虚拟”字段,例如 对齐目的。一个未命名的位域,其宽度被指定为 0 保证为跟随它的成员在 struct-declaration-list 从 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

测试3:1

测试4:4

【讨论】:

我还是不明白。这是否意味着 C++ 会自动将您的“变量”合并为 int 的大小,以便使用所有位?您能否将位字段结构转换为数字以获得典型的“int with flags”。 @TomášZato 我已经更新了我的答案,为您提供了更多信息 @JoeFish 能否详细说明test1-4的合并细节? 我不明白为什么 test4: 4 我在 Darwin Kernel Version 17.0.0 x86_64 上得到了 test4: 2 @smwikipedia 在这里避免了一个简单易懂的原则:如果 int 类型的两个字段都可以放入一个 int(即上面示例中的 32 位),则编译器只分配一个 int 值内存(test_1,test_2 的短类型,test3 的 char 类型)。在上面的示例中忽略了,如果单个 int 不能再保存位域,我们添加第二个。参考此example 以获得更详细的解释。【参考方案2】:

我也遇到了冒号符号,但在我的上下文中位字段没有意义。所以我做了一些挖掘。这种表示法也用于分配值 - 在我的特定情况下是指向函数的指针。

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

下面是一个示例和一个解释摘录。

"有一个 gcc 扩展可以更方便地分配给这个结构。你会在现代驱动程序中看到它,并且可能会让你大吃一惊。这就是新的分配方式结构如下:"

struct file_operations fops = 
   read: device_read,
   write: device_write,
   open: device_open,
   release: device_release
;

C99(旧的,兼容的)方式看起来像:

struct file_operations fops = 
   .read = device_read,
   .write = device_write,
   .open = device_open,
   .release = device_release
;

【讨论】:

我也看过这个!我一直以为 gcc 的扩展名是 .x = y 并且标准采用了它,直到后来我看到了 x: y 符号。我相信标准的看起来更好。 首先,这不是赋值,而是初始化。其次,您描述的功能(指定的初始化程序)与问题的内容(位字段)完全无关。仅仅因为过时的 GCC 扩展在语法中使用了 : 并不意味着它与问题中的 : 有任何关系。 AnT,搜索“C 结构初始化冒号”的人可能会找到这个答案,这正是我想要的。谢谢,user27346! 以后的读者需要注意:冒号出现在c结构声明(问题所属)和定义时初始化(答案所属)不是一回事。【参考方案3】:

它定义了宽度为 1 和 8 的位域。

【讨论】:

虽然准确,但答案应该解释什么是位域

以上是关于C结构中的“:”(冒号) - 这是啥意思? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

c里面冒号的意思,C语言中的冒号(:是啥意思

C语言中变量加冒号是啥意思

C++,构造函数后的冒号是啥意思? [复制]

这在 C 语言中是啥意思? [复制]

C语言结构体在定义的时候,各成员后面加冒号是啥意思?

双冒号是啥意思?