C语言 匿名联合体和匿名结构体

Posted 不咸不要钱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言 匿名联合体和匿名结构体相关的知识,希望对你有一定的参考价值。

C语言 匿名联合体和匿名结构体

匿名联合体和匿名结构体顾名思义,就是没有名字的联合体和结构体,没有名字哪怎么用?拿来用?

在嵌入式数据通信里面,大部分都是使用联合体,将有实际意义的结构体和字节数组互相转换。

typedef struct
{
    uint8_t head;     //头
    uint8_t cmd;      //功能字
    int16_t x;        //传感器x轴数据
    int16_t y;        //传感器y轴数据
    int16_t z;        //传感器z轴数据
    uint8_t end;      //尾
    uint8_t checkSum; //校验
}Packet_t;

typedef union
{
    uint8_t data[10];
    Packet_t packet;
}Datagram_t;

Datagram_t datagram;

如上所示,如果已经通过 datagram.data 接收到数据,想要从数据中提取传感器x轴数据,则只要通过 datagram.packet.x 就可以获取x轴数据。

上面的 Datagram_t 联合体中可以将 Packet_t packet;成员使用匿名结构体替换

typedef struct
{
    uint8_t head;     //头
    uint8_t cmd;      //功能字
    int16_t x;        //传感器x轴数据
    int16_t y;        //传感器y轴数据
    int16_t z;        //传感器z轴数据
    uint8_t end;      //尾
    uint8_t checkSum; //校验
}Packet_t;

typedef union
{
    uint8_t data[10];
    Packet_t;         //不给实际名字
}Datagram_t;

Datagram_t datagram;

这时想要从数据中提取传感器x轴数据,则只要通过 datagram.x 就可以获取x轴数据。

但是如果还想要保留 datagram.packet.x 这样的访问方式,怎么办?

#define INHERIT_EX(__TYPE, __NAME)  \\
            union                   \\
            {                       \\
                __TYPE;             \\
                __TYPE  __NAME;     \\
            };

typedef struct
{
    uint8_t head;     //头
    uint8_t cmd;      //功能字
    int16_t x;        //传感器x轴数据
    int16_t y;        //传感器y轴数据
    int16_t z;        //传感器z轴数据
    uint8_t end;      //尾
    uint8_t checkSum; //校验
}Packet_t;

typedef union
{
    uint8_t data[10];
    INHERIT_EX(Packet_t, packet);
}Datagram_t;

Datagram_t datagram;

可以在联合体 Datagram_t 内部在创建一个匿名联合体

    union                 
    {           
        Packet_t;           
        Packet_t  packet;    
    }; 

匿名联合体中再加上一个匿名结构体 Packet_t;
这样 就可以通过 datagram.x 和 datagram.packet.x 这两种方式访问x轴数据。

但是用了匿名联合体和匿名结构体也就是省略了调用packet 成员的步骤。
就省略了一个步骤,也没啥太大作用啊!这里的确是没有发挥太大作用,但是使用C语言开发大型项目,使用面向对象思想开发时,这个就很有用了。尤其是多层继承时,A结构体继承与B结构体、B结构体又继承C结构体… 使用匿名联合体的优势就体现出来了,A可以直接调用结构体B、C…的所有成员。

最后嵌入式开发常见的几个C编译器比如IAR MDK GCC等都是支持的匿名联合体和结构体的,如果不支持可以粘贴下面的代码到自己的系统头文件中,就可以让你的匿名代码在意思几个环境下获得支持。

/* -------------------  Start of section using anonymous unions  ------------------ */
#if defined(__CC_ARM)
  #pragma push
  #pragma anon_unions
#elif defined(__ICCARM__)
  #pragma language=extended
#elif defined(__GNUC__)
  /* anonymous unions are enabled by default */
#elif defined(__TMS470__)
/* anonymous unions are enabled by default */
#elif defined(__TASKING__)
  #pragma warning 586
#else
  #warning Not supported compiler type
#endif

以上是关于C语言 匿名联合体和匿名结构体的主要内容,如果未能解决你的问题,请参考以下文章

C语言中的匿名结构体

C语言自定义类型重难点总结(结构体位段枚举联合)

c语言联38

c语言自定义类型——结构体,位段(匿名结构体,结构体的自引用,结构体的内存对齐)

如何使用匿名结构/联合编译 C 代码?

C语言进阶之旅 (13)自定义类型