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结构中的“:”(冒号) - 这是啥意思? [复制]的主要内容,如果未能解决你的问题,请参考以下文章