【问题标题】:Simple C syntax Question简单的 C 语法问题
【发布时间】:2011-09-10 09:18:32
【问题描述】:

我在参加的 C 课程的旧考试中遇到了以下代码:

struct QuestionSet{
    char q1:1;
    char q2:1;
    char q3:1;
}

我不知道语法“char q1:1”是什么意思,而且我无法在课程书“C 编程语言”的任何地方找到它。谁能解释一下?

【问题讨论】:

  • 这么糟糕的书用作课本......
  • 重复。不过,我不能怪你没有搜索,因为仅考虑到这种古怪的语法,搜索起来相当困难。
  • 虽然我要补充一点,对于 C,你不能使用 char 作为位域,并且你应该非常注意你的位域是有符号还是无符号。跨度>

标签: c syntax


【解决方案1】:

这是一个bitfield。冒号后面的数字表示分配给结构元素的位数。所以这三个元素都是一位宽,并且能够存储两个值:0,以及 1 或 -1(取决于您的编译器,尽管在考虑二进制补码算术时 -1 会是更合乎逻辑的选项)。

【讨论】:

  • 好的,但我认为一个 char 的定义是 1 BYTE 长。它是如何工作的?
  • 不清楚char:1 位域是否可以存储值 1。首先,位域的唯一有效类型是int(在这种情况下只能签名或未签名)、signed int、unsigned int 和 _Bool。其他任何东西都是特定于编译器的扩展(但相当常见)。但如果对普通的char 进行签名,则char q1:1 可能(但不能保证)只能保存值0 和-1。普通的char 位字段是不可移植的。
  • 位字段的大小(以位为单位)由: 后面的常量指定,与声明的类型无关。
  • 我认为这里 "char q1:1" 如果我​​们使用 char 那么我们可以在这里最大字节 8 位,我的意思是 "char q1:15" 将给出错误...如果我们使用 int insted of char 那么这个限制会有所不同。这只是填充的震动......虽然简单地 unsign q1:1 也可以正常工作......
  • @cdhowie:很好——但不要忘记使用char 位域的能力根本是一个非标准的编译器扩展。真的没有理由不在这里使用unsigned int q1:1; 或signed int q1:1;。
【解决方案2】:

位域经常用于微控制器编程,因为它有助于映射内存中的寄存器。例如,对于一个 8 位的寄存器,如果每个位具有不同的含义/用途,则可以用结构体来表示寄存器值:

struct exception_register
{
    bool enable_irq_0: 1;
    bool enable_irq_1: 1;
    bool enable_irq_2: 1;
    bool enable_irq_3: 1;
    bool irq_flag_0: 1;
    bool irq_flag_1: 1;
    bool irq_flag_2: 1;
    bool irq_flag_3: 1;
};

byte* the_register = 0x1234; // where 0x1234 is the address of the register in memory.

然后启用异常 2 可以这样完成:

the_register->enable_irq_2 = true;

这比以下更具可读性:

*the_register |= (1 << 2);

这不是为了回答这个问题,但可能有助于理解位域为何有用。

【讨论】:

  • 问题是,位域可以以任何顺序存储。访问第三位域与访问第三位不同。 (它可能适用于您特定的微控制器编译器,但并非必须如此。)
  • @Chris Lutz 不知道。是的,它可能是特定于编译器的,或者可能有一些打包编译指示告诉编译器不要重新排序。
【解决方案3】:

这似乎是一个位域。 Example Bitfield

位域可能对小内存很有用。

【讨论】:

    猜你喜欢
    • 2011-02-12
    • 1970-01-01
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    • 2010-09-22
    相关资源
    最近更新 更多