系统学习C 语言(中)之 联合体、枚举篇

这是我参与11月更文挑战的第 5 天,活动详情查看:2021最后一次更文挑战

在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 语言中,可以将枚举成员视为整型常量,而将枚举变量视为整型变量。因此,可以将一个整型值初始化或者赋值给枚举变量。

Guess you like

Origin juejin.im/post/7032505058923282445