联合体(union)的使用方法和其本质

转自:http://blog.csdn.net/huqinwei987/article/details/23597091

1)联合体 union 的基本特性——和 struct 的同与不同

  union :中文名“联合体,共用体”,在某种程度上类似结构体 srtuct 的一种数据结构,union 和 struct 同样可以包含很多种数据类型和变量

  不过区别也很明显:

  struct 中所有变量是“共存”的——优点是“有容乃大”,全面;缺点是 struct 内存空间的分配是粗放的,不管用不用,全分配。

  而 union 中是各变量是 “互斥” 的——缺点就是不够 “包容” ;但优点是内存的使用更为精细灵活,也节省了内存空间。

2)双刃剑——多种访问内存途径共存

一个例子了然:

#include<stdio.h>

union var{
long int l;
int i;
};

int main(void)
{
union var v;

v.l = 5;
printf("v.l is %d\n",v.l);

v.i = 6;
printf("now v.l is %ld! the address is %p\n",v.l, &v.l);
printf("now v.i is %d! the address is %p\n",v.i, &v.i);

return 0;
}

结果:

v.l is 5

now v.l is 6 ! the address is 0x0060fefec
now v.i is 5! the address is 0x0060fefc

所以说,管 union 叫共同体还真是贴切——完全就是共用一个内存首地址,并且各种变量名都可以同时使用,操作也是共同生效。如此多的access内存手段,确实好用,不过这些手段之间却没法互相屏蔽——就好像数组+下标和指针+偏移一样。

上例中我改了 v.i 的值,结果 v.l 也能读取,那么也许我还以为 v.l 是我想要的值呢,因为上边提到了 union 的内存首地址肯定是相同的,那么还有一种情况和上边类似:

一个 int 数组变量 a,一个 long int (32 位机中,long int 占 4 字节 ,与 int 相同)变量b,我即使没给变量 b 赋值,因为数据类型相同,我使用 int 变量 b 也完全会拿出 int 数组中的 a[0] 来,一些时候一不小心用上,还以为用的就是变量 b 呢 ,

这种逻辑上的错误是很难找出来的(只有当数据类型相去甚远的时候稍好,出个乱码什么的很容易发现错误);

3)联合体 union 和大小端(big endian , little endian):

#include<stdio.h>

union var{
char c[4];
int i;
};

int main(void)
{
union var data;

/* 数组中下标低的,地址也低。按地址从低到高,内存内容依次为:04,03,02,01.总共4字节 */
/* 而把四字节作为一个整体(不分类型,直接打印十六进制),应该从内存高地址到低地址看,0x01020304 */
/* 低位04放在低地址上。 */
data.c[0] = 0x04;
data.c[1] = 0x03;
data.c[2] = 0x02;
data.c[3] = 0x01;

printf("%x\n", data.i);

return 0;
}

运行结果:

01020304

证明我的系统是小端模式( little endian )

4)联合体 union 所占内存空间的大小

前边说了,首先,union 的首地址是固定的,那么,union 到底总共有多大?根据一些小常识,做个不严谨不高深的基础版验证吧。

根据:内存分配空间的时候内存地址基本上是连续的,至少同类型能保证在一起,连续就说明,我如果弄三个结构体出来,他们三个地址应该连着,看一下三个地址的间隔就知道了。

#include<stdio.h>

union sizeTest{
int a;
double b;
};

int main(void)
{
union sizeTest unionA;
union sizeTest unionB;
union sizeTest unionC;

printf("the size of unionA is %d\n", sizeof(unionA));
printf("the size of unionB is %d\n", sizeof(unionB));
printf("the size of unionC is %d\n", sizeof(unionC));

return 0;
}

运行结果:

the size of unionA is 8

the size of unionB is 8

the size of unionC is 8

5)联合体 union 的应用场合

有了前边的那个验证,基本可以确认, union 的内存是照着里面那个最大的那个变量分的。

也是可以大胆的推测一下,这种 union 的使用场合,是各数据类型各变量占用空间差不多并且对各变量同时使用要求不高的场合(单从内存使用上说)。

6)本质和进阶

根据 union 固定首地址和 union 按最大需求 开辟一段内存空间两个特征,可以发现,所有表面的定义都是虚的,所谓联合体就是在内存里面给你划了一个足够用的空间,至于你怎么玩,它不管 ~ !(何止是 union 和 struct ,C 不就是玩地址么,所以使用 C 灵活,但是也容易犯错)

没错, union 的成员变量是相当于开辟了几个接口(即 union 包含的变量)!但是,没开辟就不能用了? 当然也能用 !

写个小测试:

#include<stdio.h>

union u{
int i;
double d;
};

int main(void)
{
union u uu;
uu.i = 10;
printf("%d\n",uu.i);

char *c;
c = (char *)&uu;

c[0] = ‘a‘;
c[1] = ‘b‘;
c[2] = ‘c‘;
c[3] = ‘d‘;
c[4] = ‘\0‘;
c[5] = ‘e‘;
c[6] = ‘f‘;
c[7] = ‘g‘;

printf("%s\n",c);
for(int j = 0; j<8 ;j++)
{
printf("%c ",c[j] );
}
printf("\n");

return 0;
}

一个例子一目了然,我的结构体只定义了 int 和 double “接口”,只要获得地址,往里面扔什么数据谁管得到?这就是 C 语言的强大,这就是 union 的本质了——只管开辟一段空间。

原文地址:https://www.cnblogs.com/beyondlpf/p/12183105.html

时间: 2024-10-22 17:32:15

联合体(union)的使用方法和其本质的相关文章

联合体union用在何处?

程序设计刚開始学习的人在学习时,总想问:"这个东东有什么用?"于是,在建设有关的教学资源时,也便总从这个角度,试图给出一些案例.这是一个将刚開始学习的人作为教学目标人群的人该干的事. 然而,在准备这样一些案例时,诸如循环.数组.结构体之类的,能够编出一堆堆的能体现实际应用的案例,或出例题,或出实践题目,都好说.然而.对于有些在教科书中的"小知识点",作为讲程序设计语言,有些老师都选择不讲的,能却总是不易编出. 基本的原因,是这些内容要解决的问题.似乎并不常见.针对特

联合体union的详解

1.概述 联合体union的定义方式与结构体一样,但是二者有根本区别. 在结构中各成员有各自的内存空间,一个结构变量的总长度是各成员长度之和.而在"联合"中,各成员共享一段内存空间,一个联合变量的长度等于各成员中最长的长度. 2.联合体长度 在The C Programming Language里面讲述union内存分配的原话是 1)联合体就是一个结构 2)联合体的所有成员相对于基地址的偏移量为0 3)此结构空间要大到总够容纳最"宽"的成员 4)并且,其对其方式要适

(C语言)共用体union的使用方法举例

曾经在学校学习C语言的时候一直搞不懂那个共用体union有什么用的.工作之后才发现它的一些妙用,现举比例如以下: 1. 为了方便看懂代码. 比方说想写一个3 * 3的矩阵,能够这样写: [ 注:以下用红色部分标记的地方是后来加入上去的,谢谢yrqing718的提醒!] struct  Matrix { union { struct { float  _f11, _f12, _f13, _f21, _f22, _f23, _f31, _f32, _f33; }; float  f[3][3]; }

Python3 第五周大纲(模块,导入方法、import本质,导入优化,模块的分类)

1.定义: 模块:逻辑上组织python代码(变量.函数.类.逻辑:实现一个功能,本质是.py结尾的文件) 2.导入方法 import module_name,module_name2,...... from module import module1,module2,.... from module import logger as xxx:等于将导入的模块起了一个别名 from module import * 可能和当前路径下的已存在模块重名 3.import本质(路径搜索和搜索路径) 导入

C++/CLI 托管C++之联合体union封装【10】

CLI封装Union时,没有对应的类型,使用的是结构体struct,指定每个元素的偏移位置. [1]声明结构体struct时,需要显示指定为Explicit. [2]每个数据需要使用FieldOffsetAttribute指定偏移位置. C++导出函数 typedef union _testStru4 { int iValLower; int iValUpper; struct { __int64 llLocation; }; }testStru4; //4.4 union类型中含有结构体 EX

结构体,联合体union,枚举,sizeof

结构体中的位字段 有些信息在存储时并不需要占用一个完整的字节,有时只需要占用一个或者几个二进制位,为了节省存储空间并使得处理简便,C语言提供了一种数据结构,成为“位域”或者“位段”. C与C++允许指定占用特定位数的结构成员,字段的类型应为整型或者枚举型 ,接下来是冒号:,然后后面跟一个数字,它指定了使用的位数,且可以使用没有名字的字段来提供间距.每个成员都被称为位字段(bit field).例: 1 struct reg 2 { 3 unsigned int SN:4; 4 unsigned

java中子类重写父类方法的思想本质

java语言中,在子类中定义与父类同返同名同参的方法将会出现"重写(覆写)",子类将屏蔽父类的相同方法,调用子类的方法将不会调用到父类的该方法. 许多初学者也许会被"覆写"一词迷惑,以为覆盖掉了父类的方法,其实这两种方法是同时独立存在的,只是子父类调用该方法的入口不一样,彼此互不干扰. 1 /* 2 需求:设计一个简单的java程序,证明子类重写父类方法的过程 3 思路: 1.创建父类对象,通过父类对象调用该方法 4 2.创建子类对象,通过父类对象调用该方法 5 3

C中联合体union共用内存

一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型.您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值. union变量的大小为其中size最大类型的大小. #include<stdio.h> union U { int a; char b; }; int main() { union U x; printf("%d\n", sizeof(x)); // 4 x.a = 97 + (98 << 0xf); // a的assic码是97

20160402_[转]联合体(union)的使用方法及其本质

原文:http://blog.csdn.net/huqinwei987/article/details/23597091 1.联合体union的基本特性——和struct的同与不同 union,中文名“联合体.共用体”,在某种程度上类似结构体struct的一种数据结构,共用体(union)和结构体(struct)同样可以包含很多种数据类型和变量. 不过区别也挺明显: 结构体(struct)中所有变量是“共存”的——优点是“有容乃大”,全面:缺点是struct内存空间的分配是粗放的,不管用不用,全