- Union
- Union定义格式
- 1、先定义、后创建变量
- 2、定义的同时创建变量
- Union初始化
- 1、初始化联合体第一个元素
- 2、联合体指定初始化
- 3、联合体初始化同类别的联合
- Union与Struct的区别
- Union的内存分布
- 1、先赋值char,再赋值short
- 2、先赋值short、在赋值char
- 大端小端
- 字节序?
- 判断大小端
联合体是一种数据类型,表示在同一个内存空间中存储不同的数据类型,联合体有时也被称为共用体,联合体只能存储一个值
联合体主要设计用于一种表以存储无规律、事先也不知道的混合类型
Union定义格式 1、先定义、后创建变量union test{ int num; short sh; char ch; }; union test t1,t2,t3;2、定义的同时创建变量
union test{ int num; short sh; char ch; }t1,t2,t3;Union初始化 1、初始化联合体第一个元素
#include2、联合体指定初始化union test{ int num; short sh; char ch; }; int main() { union test t1 = {88}; printf("t1.num=%dn",t1.num); printf("t1.sh=%dn",t1.sh); printf("t1.ch=%dn",t1.ch); return 0; }
#include3、联合体初始化同类别的联合union test{ int num; short sh; char ch; }; int main() { union test t1 = {.ch = 'A'}; printf("t1.num=%dn",t1.num); printf("t1.sh=%dn",t1.sh); printf("t1.ch=%dn",t1.ch); return 0; }
#includeUnion与Struct的区别union test{ int num; short sh; char ch; }; int main() { union test t2; t2.sh = 20; union test t1 = t2; printf("t1.num=%dn",t1.num); printf("t1.sh=%dn",t1.sh); printf("t1.ch=%dn",t1.ch); return 0; }
结构体的各个成员占用不同的内存,互相之间没有影响;联合体的所有成员都占用同一块内存,修改一个成员会影响其他成员
结构体占用的内存大于等于所有成员占用的内存的总和;联合体占用的内存等于其最大成员所占用的内存,联合体采用内存覆盖的技术,同一时刻只能保存一个成员的值,对联合体新成员赋值会将原来的值覆盖掉
Union的内存分布union test{ unsigned int num; short sh; char ch; };
上面三种初始化例子都是对联合体的单个成员进行单一赋值,联合体成员都是占用同一块内存,所以联合体每个成员输出的都是同一个值
1、先赋值char,再赋值short#includeunion test{ unsigned int num; short sh; char ch; }; int main() { union test t; //1000 ----> 11 1110 1000 //t.sh = 1000; //11101000 -----> 10010111 10011000 =- (2^4+2^3) =- (16+8) = -24 t.ch = 'a'; t.sh = 1000; // 1100001 1101100001 printf("t.num=%dn",t.num); printf("t.sh=%dn",t.sh); printf("t.ch=%dn",t.ch); return 0; }
从运行结果可以看到联合体t1的三个成员num、sh、ch分别为1000、1000、-24
首先联合体t1三个成员都占用4个字节的内存空间,首先对char类型成员进行赋值:ch=‘a’,此时联合体三个成员输出都为字符a的编码值97,然后对short类型成员进行赋值:sh=1000;因为联合体同一时刻只能保存一个值,所以1000会将之前的字符编码值覆盖掉,1000的二进制数表示为:0000 0011 1110 1000;故此时联合体的num、sh成员输出为1000,而ch成员只占用一个字节,所以此时ch表示的是sh成员的一个字节内存上的二进制数,即:1110 1000,然后负数符号位不变,其余取反加1得到补码为:1001 1000,为-24
2、先赋值short、在赋值char#includeunion test{ unsigned int num; short sh; char ch; }; int main() { union test t; //1000 ----> 11 1110 1000 t.sh = 1000; //11101000 -----> 10010111 10011000 =- (2^4+2^3) =- (16+8) = -24 //t.ch = 'a'; printf("t.num=%dn",t.num); printf("t.sh=%dn",t.sh); printf("t.ch=%dn",t.ch); printf("*************n"); t.ch = 'a'; // 1100001 1101100001 printf("t.num=%dn",t.num); printf("t.sh=%dn",t.sh); printf("t.ch=%dn",t.ch); return 0; }
从运行结果可以看到联合体t1的三个成员num、sh、ch分别为865、865、97
先赋值short类型:sh=1000,同上联合体三个成员输出分别为:1000、1000、-24
此时联合体所占用的四个字节的二进制数为0000 0011 1110 1000;然后赋值char类型:ch = ‘a’,此时ch占用第一个字节的二进制数会覆盖了之前sh在第一个字节所表示的二进制数,此时联合体占用的四个字节上的二进制数为0000 0011 0110 0001,所以此时输出联合体的ch成员时不会还是为字符编码值97,但是此时二进制数0000 0011 0110 0001转换成十进制为865
大端小端计算通常采用的字节存储方式是两种:Big-Endian和Litter-Endian
字节序?字节序:就是字节的顺序,大于一个字节类型的数据在内存中的存放顺序
Big-Endian:大端是高位字节先存储(低地址)
Litte-Endian:小端是低位字节先存储(低地址)
网络字节序:TCP/IP协议各层将字节序定义为Big-Endian,因此TCP/IP中使用的字节序被称之为网络字节序,也就是大端
*** 作系统一般都是小端
高低字节:不论什么进制,靠近左边的称之为高位字节,靠近右边为低位字节
**就拿 0x12345678来说,从高位到低位的字节依次是0x12、0x34、0x56和0x78。**
Big-Endian:最不重要字节(LSB)存放在最低端的地址上
Litter-Endian:最不重要字节(LSB)存放在最低端的地址上
判断大小端#includeunion endian { int a; char ch; }; int main() { union endian value; value.a = 0x1234; if (value.ch == 0x12) printf("big endiann"); else if (value.ch == 0x34) printf("little endiann"); }
总结
联合体是一种数据类型,表示在同一个内存空间中存储不同的数据类型,只能存储一个值,同一时刻只能保存一个成员的值,对联合体新成员赋值会将原来的值覆盖掉
赶紧学习起来吧!我是一个正在努力找回自我的人,希望能和一起学习的人成长,有错误的地方请各位大佬帮忙指正,如果觉得有帮助就点个赞当作对我的一个小肯定❤,peace&love
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)