联合内的数据结构(C 编程)
Data Structure inside a Union (C Programming)
每当结构被放入其他结构中时,我都会出于某种原因感到困惑。我正在为 I2C(2 线串行接口)设备编写驱动程序,并使用制造商驱动程序作为创建我的驱动程序的参考。我在下面有这个联合声明(在头文件中定义),我只是无法理解其中的几行。只是一个简短的背景,所以你知道你在看什么是下面的主要片段是设置这个 TWI_statusReg 变量,每次我在 I2c 上 transmitting/receiving 数据时,它保存来自状态寄存器的信息公共汽车。该数据寄存器长 8 位,属于 Atmel Atmega328P 微控制器。这是我的问题...
1.) 这个问题很难用语言来表述,但是你能用简单的术语解释一下为什么要在这样的联合结构中声明一个数据结构吗?我应该从中挑出哪些重点?
2.) 在此处post太长的“.c”头定义文件中,有一行内容如下
TWI_statusReg.all = 0;
我知道头文件中有一个名为 'all' 的 char 变量,如下面的主要代码片段所示。但是,我不明白当它被分配为零时会发生什么。这是将状态寄存器中的所有位设置为零吗?
3.) 两行
unsigned char lastTransOK:1;
unsigned char unusedBits:7;
冒号运算符具体在做什么让我感到困惑。
代码的主要片段
/****************************************************************************
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;
1) 写这样一个union主要是为了方便。您现在不必每次需要访问特定位时都手动设置位掩码,而是为这些位设置别名。
2) 联合让您可以引用内存,就好像它的组件是代表不同类型的不同变量一样。联合体只分配 space 给其中最大的部分。所以如果你有
union Example {
char bytes[3];
uint32_t num;
};
这样的联合会占用 4 个字节,因为它的最大类型 uint32_t
占用 space 的 4 个字节。不过,拥有这样的联合可能更有意义,因为无论如何您都在使用 space 并且它更方便:
union Example {
char bytes[4];
uint32_t num;
};
bytes 数组将允许您访问 num 的各个字节。
您的猜测是正确的 - 将值写入 all 将设置并集的相应位。
3) 这个构造称为 bit field
,是对内存使用的优化——如果你要使用 2 个字符的结构,它实际上需要 2 个字节的内存 space,相反,如果您声明一个位字段,它将只占用 1 个字节(并且您还有 6 个 "unused" 位)
每当结构被放入其他结构中时,我都会出于某种原因感到困惑。我正在为 I2C(2 线串行接口)设备编写驱动程序,并使用制造商驱动程序作为创建我的驱动程序的参考。我在下面有这个联合声明(在头文件中定义),我只是无法理解其中的几行。只是一个简短的背景,所以你知道你在看什么是下面的主要片段是设置这个 TWI_statusReg 变量,每次我在 I2c 上 transmitting/receiving 数据时,它保存来自状态寄存器的信息公共汽车。该数据寄存器长 8 位,属于 Atmel Atmega328P 微控制器。这是我的问题...
1.) 这个问题很难用语言来表述,但是你能用简单的术语解释一下为什么要在这样的联合结构中声明一个数据结构吗?我应该从中挑出哪些重点?
2.) 在此处post太长的“.c”头定义文件中,有一行内容如下
TWI_statusReg.all = 0;
我知道头文件中有一个名为 'all' 的 char 变量,如下面的主要代码片段所示。但是,我不明白当它被分配为零时会发生什么。这是将状态寄存器中的所有位设置为零吗?
3.) 两行
unsigned char lastTransOK:1;
unsigned char unusedBits:7;
冒号运算符具体在做什么让我感到困惑。
代码的主要片段
/****************************************************************************
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;
1) 写这样一个union主要是为了方便。您现在不必每次需要访问特定位时都手动设置位掩码,而是为这些位设置别名。
2) 联合让您可以引用内存,就好像它的组件是代表不同类型的不同变量一样。联合体只分配 space 给其中最大的部分。所以如果你有
union Example {
char bytes[3];
uint32_t num;
};
这样的联合会占用 4 个字节,因为它的最大类型 uint32_t
占用 space 的 4 个字节。不过,拥有这样的联合可能更有意义,因为无论如何您都在使用 space 并且它更方便:
union Example {
char bytes[4];
uint32_t num;
};
bytes 数组将允许您访问 num 的各个字节。
您的猜测是正确的 - 将值写入 all 将设置并集的相应位。
3) 这个构造称为 bit field
,是对内存使用的优化——如果你要使用 2 个字符的结构,它实际上需要 2 个字节的内存 space,相反,如果您声明一个位字段,它将只占用 1 个字节(并且您还有 6 个 "unused" 位)