在struct中使用union的目的是什么?

时间:2017-08-24 01:20:00

标签: c++ c struct

我目前正在努力使用嵌入式UART程序中的uart代码段。

然后,当我分析代码时,我发现了我无法理解的内容。

Q1。如果使用" union" in" struct"。这样做的好处和用途是什么?

#define     __IO    volatile   

typedef struct {
  union {
  __IO  uint32_t RR;
  __IO  uint32_t TR;
  __IO  uint32_t DL;
  __IO  uint32_t RR_TR_DL;
  };
  union {
  __IO  uint32_t DH;
  __IO  uint32_t IR;  
  __IO  uint32_t DH_IER;
  };
} UART_TypeDef;

Q2。如果使用" union" in" struct" in" struct"。有什么好处,有什么用途?

typedef struct {
  union {
  struct{
    __IO   uint32_t CTRLR0; 
    __IO   uint32_t SSI_COMP_VERSION;  
    union {
    __IO   uint32_t DR;              
    __IO   uint32_t DR0;            
    };
    __IO   uint32_t DR1;            
    __IO   uint32_t RSVD_2;       
  };
  uint8_t RESERVED[0x1000];     
  };
} SSI_TypeDef;

1 个答案:

答案 0 :(得分:2)

第一种情况基本上是#34;别名"字段名称。 UART_TypeDef类型包含两个uint32_t字段,第一个字段可以称为RRTRDLRR_TR_DL中的任意一个。同样适用于第二个字段,可以是DHIRDH_IER

第二种情况SSI_TypeDef内部联盟类似,由三个uint32_t字段组成,CTRLR0/SSI_COMP_VERSIONDR/DR0DR1/RSVD_2(在所有情况下,任一名称都可以用于字段)。

但由于与uint8_t RESERVED[0x1000]结合,整个结构的大小为4K。

例如,如果相同的基础字段可以作为RRTR访问,则根据上下文,别名很有用。例如,设备可能具有不同的行为,具体取决于您是读取还是写入位置。

例如,假设您到给定地址(内存映射I / O操作),以向另一端指示您已准备就绪(能够接收数据)。进一步假设读取完全相同的位置会让您知道您是否能够传输。

首先,让我们设置所说的内存映射I / O地址(比如说0xf000):

UART_TypeDef *utd = (UART_TypeDef *)0xf000; // very shifty :-)

现在这两个这些语句引用相同的内存地址:

int transmitReady = utd->TR; // Can I transmit?
utd->RR = 1;                 // Tell other end it can send.

能够为相同的基础事物使用不同的名称有助于提高可读性。