【C语言】自定义类型:联合和枚举

云边有个稻草人 2024-07-26 13:35:01 阅读 99

前言

前面我们学习了一种自定义类型,结构体,现在我们学习另外两种自定义类型,联合 和 枚举

目录

一、联合体

1.  联合体类型的声明

2.  联合体的特点

3.  相同成员联合体和结构体对比

4.  联合体大小的计算

5.  用联合体判断当前机器大小端

二、枚举

1.  枚举类型的声明

2.  枚举类型的优点

3.  枚举类型的使用


正文开始——

一、联合体

1.  联合体类型的声明

与结构体一样,联合体是由一个或多个成员构成,这些成员可以是不同的类型。

<code> #include<stdio.h>

//联合体类型的声明 union是关键字

union Un

{

char c;

int i;

};

int main()

{

//联合体变量的定义

union Un un={0};

//计算联合体变量的大小

printf("%zd\n",sizeof(un));

return 0;

}

2.  联合体类型的特点

联合的成员是共用一块内存空间的(所以联合体也叫共用体),所以联合变量的大小至少是最大成员的大小,因为联合体至少得有能力保存最大的那个成员。

代码 1 及其运行结果

<code> #include<stdio.h>

//联合类型的声明

union Un

{

char c;

int i;

};

int main()

{

union Un un={0};

printf("%p\n",&(un.c));

printf("%p\n",&(un.i));

printf("%p\n",&un);

return 0;

}

代码 2  及其运行结果

<code> #include<stdio.h>

//联合类型的声明

union Un

{

char c;

int i;

};

int main()

{

union Un un={0};

//联合变量的定义

un.i=0x11223344;

un.c=0x55;

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

return 0;

}

图解见下:

i 和 c 共用一块内存空间,所以联合体也叫共用体,同一时间只能使用 i 和 c 中的一个。

3.  相同成员的结构体和联合体对比

我们再对比一下相同成员的结构体和联合体的内存布局情况。

<code> struct S

{

char c;

int i;

};

struct S s={0};

union Un

{

char c;

int i;

};

union Un un={0};

4.  联合体大小的计算

联合体的大小至少是最大成员的大小。当最大成员的大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

<code> #include<stdio.h>

union Un1

{

char c[5];

int i;

};

union Un2

{

short c[7];

int i;

};

int main()

{

printf("%zd\n",sizeof(union Un1));

printf("%zd\n",sizeof(union Un2));

return 0;

}

计算一个数组的大小,就是这个数组类型大小 * 数组成员个数

【例如】

short [7],2*7=14。

对于 union Un2,我们来计算,首先最大成员的大小是14,最大对齐数为 4,但是14不是最大对齐数的整数倍,那就要对齐到最大对齐数的整数倍,即为16。union Un1同理。

我们发现,对于同样成员的结构体和联合体,联合体有时会占用更少的内存,可以节省空间。

下面我们举个栗子,看看在什么情况下适用联合体。

我们要搞一个活动,要上线一个礼品兑换单,礼品兑换单中有三种商品:图书、杯子、衬衫。每种商品都有:库存量、价格、商品类型和商品类型相关的其他信息。

图书:书名、作者、页数

杯子:设计

衬衫:设计、可选颜色、可选尺寸

以结构体的的方式写

struct gift_list

{

//公共属性

int stock_number;//库存量

double price; //定价

int item_type; //商品类型

//特殊类型

char title[20]; //书名

char author[20]; //作者

int num_pages; //页数

char design[30]; //设计

int colors; //颜色

int sizes; //尺寸

};

这样的结构体设计很简单,用起来也比较方便,但是其中包含了所有的属性,这样就导致结构体的大小就会偏大,浪费内存,并且其中属性并非所有的商品都有。所以我们可以把公共的属性单独写出来,剩余属于各种商品本身的属性使用联合体,这样可以节省内存空间。

struct gift_list

{

//公共属性

int stock_number;//库存量

double price; //定价

int item_type; //商品类型

union

{

struct

{

char title[20]; //书名

char author[20]; //作者

int num_pages; //页数

}book;

struct

{

char design[30]; 设计

}mug;

struct

{

char design[30]; //设计

int colors; //颜色

int sizes; //尺寸

}shirt;

}item;

};

上面结构体和联合体都是匿名,因为这些类型只会被使用一次。

5.  用联合体判断当前机器大小端  

写一个程序,判断当期机器是大端,还是小端。

int check_sys()

{

union Un

{

char c;

int i;

};

un.i=1;

return un.c;

}

二、枚举

1.  枚举类型的声明

枚举即列举,把可能取值一一列举出来。

enum Day

{

Mon;

Tues;

Wed;

Thur;

Fri;

Sat;

Sun;

};

上面定义的 enum Day 是枚举类型。{} 里面的内容是枚举类型的可能取值,也叫 枚举常量

这些可能取值都是有值的,默认从0开始,依次递增1,在声明枚举类型的时候也可以赋初值。

enum Color

{

Blue=3

Red=4;

Pink=7;

Black=9;

};

2.  枚举类型的优点

我们可以使用 #define 定义常量,为什么要使用枚举类型?

增加代码的可读性和可维护性;和 #define 定义的标识符比较枚举有类型检查,更加严谨;便于调试,预处理阶段会删除 #define 定义的符号;使用方便,一次可以定义多个常量;枚举常量遵循作用域规则,枚举声明在函数内,只能在函数内使用。

3.  枚举类型的使用

enum Color

{

RED=3;

GREEN=6;

};

enum Color clr = GREEN; //使用枚举常量给枚举变量赋值


完——

期待我们下一次相遇——

像极了_永彬Ryan.B_高音质在线试听_像极了歌词|歌曲下载_酷狗音乐酷狗音乐为您提供由永彬Ryan.B演唱的高清音质无损像极了mp3在线听,听像极了,只来酷狗音乐!

icon-default.png?t=N7T8

https://t1.kugou.com/song.html?id=2rsi1cbCPV2



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。