嵌入式C编程

6

以下是我的ZigBee WSNDemo代码片段,其中的结构体让我很难理解。我看了很多相关的文章,但仍然不明白这些结构体变量是如何定义和使用的。请帮忙解释一下。

     static struct
     {
       uint8_t appSubTaskPosted  : 1;
       uint8_t appCmdHandlerTaskPosted  : 1;
       uint8_t appMsgSenderTaskPosted  : 1;
     } appTaskFlags =
       {
         .appSubTaskPosted = false,
         .appCmdHandlerTaskPosted = false,
         .appMsgSenderTaskPosted = false
        };

false 必须是宏展开,因为 C 没有 bool 类型。 :1 表示在 uint8_t 中只使用 1 位(在这种情况下,类似于 0 或 1 的 true 或 false)。 其余部分只是结构的初始化。 - H_squared
3
C语言确实有bool类型。它在14年前引入了这种数据类型。 - Lundin
@Lundin 很好知道。我在使用 C 中的布尔值时一直使用宏。 - H_squared
2个回答

5
它们是位字段,这种情况下只有1个比特。它们只能取值0或1,即真或假。它们单独占用的内存比bool类型少。
你还可以定义大于1的位字段。例如,一个2位的位字段可以有值0、1、2和3。位字段的好处是无需使用较大数据类型的单个位来访问它们所需的偏移量。
如果您要定义包含位字段的结构,请将它们直接定义在一起,因为像这样的位字段实际上共享较大的数据类型,例如int 32。

1
位域共享的数据类型是用于声明它们的数据类型。我记不清这是由标准规定还是常见的实现惯例。 - Potatoswatter

5
您在问题中并没有明确指出您不理解的是什么,但是在您的示例中至少有四个东西可能不会在“经典”的C文献或在结构方面的一般搜索中找到。这些是:
- 位字段成员 - 指定初始化程序 - 显式宽度数据类型 - 布尔文字常量
位字段一直存在于ISO/ANSI C中,但并不常用。虽然它们可以产生内存高效的数据结构,但在大多数体系结构上,它们会生成更多的代码来访问,并且访问可能不是原子的,在数据在中断或线程上下文之间共享时就会出现问题。此外,位字段的打包是实现定义的,因此可能会导致非便携式代码在应用程序中,其中确切的位位置很关键(例如当覆盖硬件寄存器时)。
指定初始化程序是在ISO C99中引入的。关于C99的特定文献并不多,大多数C文献都是C90的前身或为了兼容性而坚持使用C90子集。如果您想查找此类信息,您应该专门搜索C99。

显式宽度数据类型(在本例中为uint8_t)也在C99中引入,但只是作为内置类型的typedef别名实现在标准头文件stdint.h中,因此也可以在C90编译器中实现。

同样,布尔字面量truefalse也与bool数据类型一起在C99中引入。在C99中,bool是在stdbool.h中定义的_Booltypedef别名,同时定义了truefalse。如果选择这样做,您可以在C90中定义booltruefalse,但它缺少内置的_Bool数据类型,因此您需要将其命名为其他整数类型的别名。


我想我应该提到你指出的那些术语,那正是我在寻找的。现在我感到很平静。谢谢兄弟。 - DarshanJoshi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接