在C语言中有一个和结构体非常像的数据类型,它的名字叫做联合体,也被称为共用体或公用体。
1,联合体
1,联合体的定义
定义联合体需要使用"union" 关键字,格式如下:
union 联合体名{
数据类型 成员1;
数据类型 成员2;
...
};
2,联合体的大小
联合体和结构体最大的区别就是在内存存储上。结构体的每个成员都有自己独立的内存空间,结构体大小为所有成员的大小之和(不考虑内存对齐情况)。而联合体的所有成员都使用同一段内存空间,联合体的大小即为联合体中最大的那个成员大小。例如定义下面一个联合体:
union A {
char a;
int b;
double c;
};
最大的成员是double 类型的 c ,大小为8个字节。因此联合体的大小就是c 的大小。同样,我们也可以用 sizeof运算符来获取联合体A 的大小。
3,联合体变量的初始化
因为联合体不能同时存储多个成员的值。所以,在初始化的时候,只应对一个成员进行初始化,即初始化列表中只放一个初始值。*在默认情况下,会将这个初始值给联合体变量的第一个成员。*例如:
union A a1 = {'A'};
如果想对其他位置的成员进行初始化,则可以通过指定初始化方式。例如:
union A a1 = {.b=35}; //通过指定初始化将联合体变量a1的成员b初始化值为35
4,联合体变量的访问和赋值
对联合体变量中的成员赋值,也是使用成员访问运算符,即点运算符。如下:
union A a1 = {'A'};
printf("Member a : %c\n",a1.a); //输出结果为 Member a :A
联合体应用案例
在计算机网络中,两台计算机要想通信,就需要知道彼此的ip 地址。那我们思考一下如何存储类似于“192.168.0.1”的点分格式的ip 地址呢?
下面我们就编写程序,由用户输入一个ip地址,程序可以将其转换为4 字节整型类型的IP 地址值,并打印输出:代码如下:
#include<stdio.h>
union IP{
unsigned char str[4];
unsigned int digit;
};
int main(){
union IP ip; //定义联合体变量ip
printf("Please enter IP address in string format:\n");
//接收用户输入的IP地址,并将其存储至字符数组
scanf("%d.%d.%d.%d",&ip.str[0],&ip.str[1],&ip.str[2],&ip.str[3]);
//打印输出数字格式的IP地址值
printf("IP address in digital format is: %u\n",ip.digit);
return 0;
}
2,枚举
C语言中,还允许定义枚举类型。使用枚举类型,可以提高程序代码的健壮性和可读性,并且枚举成员属于常量。
1,枚举的定义
枚举的定义格式为:
enum 枚举名{枚举成员1,枚举成员2,...};
例如定义一个和方向相关的枚举类型Dir:
enum Dir{up,down,left,right};
前面说了,枚举成员是常量,既然是常量,就应该有对应的值,那上面的四个方位的值又是多少呢?那下面就让输出语句告诉我们吧:
printf("up = %d\n",up);
printf("down = %d\n",down);
printf("left = %d\n",left);
printf("right = %d\n",right);
//运行结果如下:
up = 0;
down =1;
left = 2;
right =3;
是否发现了什么呢?是的,默认情况下,枚举成员是一个整型值,其第一个枚举成员的值为0,而后续枚举成员的值为其前一个枚举成员的值加1。
那是否能够自己设置枚举成员的值呢?当然是可以的。例如:
enum Dir{up,down = 10,left,right};
//同样通过printf 语句输出结果就是你想的那样:
up = 0;
down = 10;
left =11;
right =12;
2,枚举变量的定义
枚举变量的定义与结构体和联合体的变量定义方式类似,如通过如下几种方式:
enum Dir dir1; //先定义枚举,再定义枚举变量
enum Dir{up=2,down,left,right}dir2; //在定义枚举的同时定义枚举变量
enum {up=2,down,left,right}dir3; //定义无名枚举类型的枚举变量
最后,C 语言中,可以将枚举成员视为整型常量,而将枚举变量视为整型变量。因此,可以将一个整型值初始化或者赋值给枚举变量。