C语言中的自定义类型:union共用体
1.共用体的使用
共用体union
和结构体struct
在类型定义、变量定义、使用方法上很相似。
举个栗子:
#include<stdio.h>
struct my_struct{ //定义一个结构体
int a;char b;
};
union my_union{ //定义一个共同体
int a;char b;
};
int main(int argc,char**argv)
{
struct my_struct tmp1;//定义一个结构体变量
printf("%p--%p.\n",&tmp1.a,&tmp1.b);
union my_union tmp2;//定义一个共同体变量
printf("%p--%p.\n",&tmp2.a,&tmp2.b);
printf("size of struct = %d.\n",sizeof(tmp1));
printf("size of union = %d.\n",sizeof(tmp2));
return 0;
}
输出:
0x7ffdeebbfd50--0x7ffdeebbfd54.
0x7ffdeebbfd40--0x7ffdeebbfd40.
size of struct = 8.
size of union = 4.
共用体和结构体的不同之处在于:
- 1.结构体类似于一个包裹,结构体中的成员彼此是独立存在的,分布在内存的不同单元中,他们只是被打包成一个整体叫做结构体而已,从上面代码的输出可以看出,结构体内
a
和b
占用不同的地址。 - 2.共用体中的各个成员其实是一体的,彼此不独立,他们使用同一个内存单元。更准确的说法是同一个内存空间中存储的二进制数据有多种解释方式。
具体的说,共同体内的a
,b
实际占用同一块内存,当我们使用tmp2.a
时,就按照int
类型来解析这个内存空间中的二进制机器数,使用tmp2.b
时,就按照char
类型来解析内存空间中的二进制机器数。
共同体的sizeof
测到的大小实际是共同体中各个元素里面占用内存最大的那个元素的大小,因为可以存的下这个就一定能够存的下其他的元素,例如上面代码中定义的共同体,大小就是4字节,因为它的成员中最大的就是占4字节的int
型变量。
共同体中的元素不存在内存对齐的问题,因为共同体中实际只有一个内存空间,共用体里的成员都是从同一个地址开始的,开始地址就是整个共同体占有的内存空间的首地址,所以不涉及内存对齐。
2.关于数据类型的理解
真值与机器数的概念:日常生活中我们看到的+5,-8等带有+,-符号的数值就是真值。但是计算机不认识+,-符号,我们知道二进制有0和1,刚好就可以表示一个数的正负两种符号,这样一个真值就可以数值化成机器数了,所谓机器数,就是实际存储在计算机里面的数据形式,它有原码,补码,反码等形式。
3.共用体的主要用途
共用体就用在那种对同一个内存单元进行多种不同规则解析的这种情况下。
举个栗子:
#include<stdio.h>
union my_union{ //定义一个共同体
int a;
float b;
};
int main(int argc,char**argv)
{
union my_union tmp2;
tmp2.a = 1234567891;
printf("共用体方式 = %f.\n",tmp2.b);
int a = 1234567891;
printf("指针方式 = %f.\n",*((float*)&a));
return 0;
}
输出:
共用体方式 = 1228890.375000.
指针方式 = 1228890.375000.
C
语言中其实是可以没有共用体的,用指针和强制类型转换可以替代共用体完成同样的功能,但是共用体的方式更简单、更便捷、更好理解。