C语言之联合体

1.说明

union在C中本质上是一个结构体,用法和struct相似,定义如下:

union 名称 
{
    //... 成员
};

声明如下(要在名称前加上关键字union):

union 类型名称 变量名称;

调用如下(用expression.identifier的形式来调用成员):

a.member1 = 10; // a为union
p->member1 = 20; // p为union的指针

2.联合体union和struct的异同之处

union,意为联合体、共用体,而struct,意为结构体,作为特殊的数据结构类型,其相同之处在于:

共用体(union)和结构体(struct)同样可以包含很多种数据类型和变量。

不同之处在于:

结构体(struct)中所有变量是“共存”的——优点是“有容乃大”,全面;相应的,其缺点是struct内存空间的分配是粗放的,不管用不用,全分配,因此所占用的内存也相对较大。

而联合体(union)中是各变量是“互斥”的——缺点就是不够“包容”,同一时刻,只能为其定义的某一种数据类型分配内存,而不是为每一个数据成员配置空间;但优点是内存使用更为精细灵活,也节省了内存空间。

3.union的特点

在union 中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,按最大需求开辟一段内存空间,并且所有的数据成员具有相同的起始地址(即固定首地址)。

4.大小端模式对union 类型数据的影响

下面看一个例子:

union
{
   int i;
   char a[2];
}*p, u;
p =&u;
p->a[0] = 0x39;
p->a[1] = 0x38;

p.i 的值应该为多少呢?

这里需要考虑存储模式:大端模式和小端模式。

  1. 大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。
  2. 小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中。

union 型数据所占的空间等于其最大的成员所占的空间。对union 型的成员的存取都是相对于该联合体基地址的偏移量为0 处开始,也就是联合体的访问不论对哪个变量的存取都是从union 的首地址位置开始。

那么,如何用程序确认当前系统的存储模式?写一个函数,若处理器是Big_endian ,返回0;若Little_endian ,则返回1。

先分析一下,按照上面关于大小端模式的定义,假设int 类型变量i 被初始化为1。

以大端模式存储,其内存布局如下图:

以小端模式存储,其内存布局如下图:

变量i 占4 个字节,但只有一个字节的值为1,另外三个字节的值都为0。如果取出低地址上的值为0,这是大端模式;如果取出低地址上的值为1,则是小端模式。既然如此,我们完全可以利用union 类型数据的特点:所有成员的起始地址一致来写目标函数:

int checkSystem( )
{
   union check
   {
      int i;
      char ch;
   } c;
   c.i = 1;
   return (c.ch ==1);
}

猜你喜欢

转载自blog.csdn.net/W614171629/article/details/81100136
今日推荐