【问题标题】:Data Structure inside a Union (C Programming)联合内的数据结构(C 编程)
【发布时间】:2016-10-08 23:39:05
【问题描述】:

任何时候结构都被扔进其他结构中,我只是出于某种原因感到困惑。我正在为 I2C(2 线串行接口)设备编写驱动程序,并使用制造商驱动程序作为创建我的驱动程序的参考。我在下面有这个联合声明(在头文件中定义),我只是无法理解其中的几行。只是一个简短的背景,所以你知道你在看什么是下面的主要 sn-p 设置这个 TWI_statusReg 变量,每次我通过 I2c 总线发送/接收数据时,它都会保存来自状态寄存器的信息。该数据寄存器为 8 位长,属于 Atmel Atmega328P 微控制器。这是我的问题...

1.) 这个问题很难用语言来表达,但是你能用简单的术语解释一下为什么你会在这样的联合结构中声明一个数据结构吗?我应该从中挑出哪些关键点?

2.) 在“.c”头文件定义文件太长,无法在此处发布,有一行内容如下

TWI_statusReg.all = 0;

我知道头文件中有一个名为“all”的 char 变量,如下面代码的主要 sn-p 所示。但是,我不明白当它被分配为零时会发生什么。这是否将状态寄存器中的所有位都设置为零?

3.) 两行

unsigned char lastTransOK:1;
unsigned char unusedBits:7; 

让我特别困惑的是冒号运算符在做什么。

CODE的主要sn-p

/****************************************************************************
  Global definitions
****************************************************************************/

union TWI_statusReg                       // Status byte holding flags.
{
    unsigned char all;
    struct
    {
        unsigned char lastTransOK:1;      
        unsigned char unusedBits:7;
    };
};

extern union TWI_statusReg TWI_statusReg;

【问题讨论】:

  • 冒号运算符指定用于该字段的位数。
  • 而且位域是不可移植的。我知道没有任何独立于平台的方式可以知道all 的哪一位对应于lastTansOK 位。它可能是第一位,也可能是最后一位。如果你使用不同的编译器,它可能会改变。
  • 如果TWI_statusReg.all = 0; 在头文件中(在inline 函数或宏之外,它对代码质量的影响非常糟糕。你的问题很困惑和不清楚。最好是得到一本 C 书并阅读有关 structs 和 unions 的部分。
  • @AndrewHenle 以下行在现有驱动程序中被大量使用.......TWI_statusReg.lastTransOK = TRUE;........但是,我明白你的意思没有办法知道。
  • @Code-Apprentice 它不是运算符(运算符对表达式进行操作)

标签: c data-structures unions atmega atmel


【解决方案1】:

1) 编写这样一个联合的主要原因是方便。无需每次需要访问特定位时手动进行位掩码,您现在可以为这些位设置别名。

2) 联合让您可以引用内存,就好像它的组件是代表不同类型的不同变量一样。联合只为其中最大的组件分配空间。所以如果你有

union Example {
      char bytes[3];
      uint32_t num;
};

这样的联合将占用 4 个字节,因为它的最大类型 uint32_t 占用 4 个字节的空间。不过,拥有这样的联合可能更有意义,因为无论如何您都在使用该空间并且更方便:

union Example {
      char bytes[4];
      uint32_t num;
};

bytes 数组将允许您访问 num 的单个字节。

您的猜测是正确的 - 将值写入 all 将设置并集的相应位。

3) 这个结构叫做bit field,是内存使用的优化——如果你使用2个字符的结构,它实际上会占用2个字节的内存空间,而不是你声明一个位字段只需要 1 个字节(而且您还有 6 个“未使用”位)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多