联合和枚举

目录

1.联合体

1.1联合体的声明

1.2联合体的特点

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

1.4联合体大小的计算

1.5练习

2.枚举

2.1枚举类型的声明

2.2枚举类型的优点

2.3枚举使用


1.联合体

1.1联合体的声明

联合体也是由一个或者多个成员构成,这些成员可以不同的类型。但是 编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同一块内存空间。所以联合体也叫:共用体。

给联合体其中一个成员赋值,其他成员的值也跟着变化

#include<stdio.h>

union Un//联合体声明
{
    char c;
    int i;
};
int main()
{
    union Un un={0};//定义联合体变量
    printf("%d\n",sizeof(un));
    return 0;
}
    

1.2联合体的特点

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

//代码1
#include <stdio.h>
//联合类型的声明
union Un
{
 char c;
 int i;
};
int main()
{
 //联合变量的定义
 union Un un = {0};
 // 下⾯输出的结果是⼀样的吗?
 printf("%p\n", &(un.i));
 printf("%p\n", &(un.c));
 printf("%p\n", &un);
 return 0;
}
//输出的结果是一样的,因为联合体的成员共用一个空间
那么不管是整个联合体的首地址,又或者是其中成员的首地址,就都是一样的了

//代码2
#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;
}

输出结果是11223355
因为int类型占4字节,联合体会申请4字节的空间,这空间是联合体成员共用的
而char类型占1字节,所以如果要共用的话,char类型会将int类型数据的低位字节替换掉

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

struct S
{
 char c;
 int i;
};
struct S s = {0};

首先c变量会从偏移量0开始,占一个字节
接着int类型又是4字节,然后vs默认字节数8,所以取4
偏移量1不是4的倍数,所以跳到偏移量4开始,占4个字节


union Un
{
 char c;
 int i;
};

union Un un = {0};
由于最大的类型是int,所以联合体的空间申请的4个字节
而这4个字节中,int类型数据的高位3个字节占据4个字节中的3个字节,
剩下char类型再占据剩下的1个字节


1.4联合体大小的计算

联合的大小至少是最大成员的大小

当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍

#include <stdio.h>
union Un1
{
 char c[5];
 int i;
};
union Un2
{
 short c[7];
 int i;
};
int main()
{
 //下⾯输出的结果是什么?
 printf("%d\n", sizeof(union Un1));
 printf("%d\n", sizeof(union Un2));
 return 0;
}

//因为char类型本身只有1个字节,vs默认字节数是8,取1
但char类型数组,一共占了5个字节,然后int类型是4字节,但偏移量5不是4的倍数
所以int类型会从偏移量8开始,前面的空间会浪费掉,所以要申请8个字节
//第二个,因为是short类型,一共14个字节,然后int类型只占4字节,
但为了匹配整数倍,所以要申请16个字节

联合体可以节省空间:

我们要搞一个活动,要上线一个礼品兑换单,礼品兑换单中有3种商品:图书、杯子、衬衫。

每种商品都有:库存量、价格、商品类型和商品类型相关的其他信息

图书:书名、作者、页数

杯子:设计

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

简单粗暴的设计:
 

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;
};

//将公用的属性直接放入结构体,但特有的属性
通过联合体,在联合体内部创建3个不同商品特有属性的结构体
这样联合体运用时只会使用相应的商品属性

1.5练习

int check_sys()
{
 union
 {
 int i;
 char c;
 }un;
 un.i = 1;
 return un.c;
}
//由于联合体中,小类型占据空间是从最大类型的低位地址开始占据,
因此un.c可以看到低位地址的内容
那么如果un.c的值是低位数据也就是1,那么就是小端,如果是0,那就是大端

2.枚举

2.1枚举类型的声明

枚举就是列举

把可能值一一列举

enum Day//星期
{
 Mon,//默认0
 Tues,//递增1,所以是1
 Wed,
 Thur,
 Fri,
 Sat,
 Sun
};
enum Sex//性别
{
 MALE,
 FEMALE,
 SECRET
};
enum Color//颜⾊
{
 RED,
 GREEN,
 BLUE
};
{}中的内容是可能取值,也是枚举常量
这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值

2.2枚举类型的优点

枚举可以增加代码可读性和可维护性—可以将一些数字赋予常量,然后将常量直接拿来使用。这些枚举变量可以直接代表相应的枚举常量

和define相比,枚举有类型检查,更严谨

便于调试,预处理阶段会删除define定义的符号

可以一次性定义多个常量

枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用

2.3枚举使用

enum Color//颜⾊
{
 RED=1,
 GREEN=2,
 BLUE=4
};
enum Color clr = GREEN;//使⽤枚举常量给枚举变量赋值

在c语言中可以拿整数给枚举变量赋值,但C++不行,c++的检查类型比较严格。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值