罗湖网站公司,自动下单网站开发,冒用他人公司做网站,做网站的实训报告欢迎来到白刘的领域 Miracle_86.-CSDN博客
系列专栏 C语言知识
先赞后看#xff0c;已成习惯 创作不易#xff0c;多多支持#xff01; 在编程的世界中#xff0c;枚举和联合体是两种非常基础且重要的数据结构。它们各自具有独特的特点和用途#xff0c;为程序员提供…欢迎来到白刘的领域 Miracle_86.-CSDN博客
系列专栏 C语言知识
先赞后看已成习惯 创作不易多多支持 在编程的世界中枚举和联合体是两种非常基础且重要的数据结构。它们各自具有独特的特点和用途为程序员提供了灵活且强大的工具来构建复杂而高效的程序。
目录
一、联合体
1.1 联合体类型的声明
1.2 联合体的特点
1.3 相同成员的结构体和联合体的比较
1.4 联合体大小的计算
1.5 填坑
二、枚举
2.1 枚举的声明
2.2 枚举的优点
2.3 枚举的使用 一、联合体
1.1 联合体类型的声明
像结构体一样联合体也是由一个或者多个成员构成这些成员可以是不同的类型。
但是与结构体不同的是编译器只为联合体中最大的成员分配足够的内存空间。联合体的一个显著特点是它的所有成员共同使用同一块内存空间。因此联合体也被称为“共用体”。
由于所有成员共享同一块内存所以当给联合体的其中一个成员赋值时其他成员的值也会跟着发生变化因为它们实际上是在操作同一块内存的不同部分。这种特性使得联合体在某些特定的编程场景中非常有用但也需要在使用时格外小心以避免出现意料之外的数据覆盖或混淆。
#include stdio.h
//联合类型的声明
union Un
{char c;int i;
};
struct Stu
{char c;int i;
};int main()
{//联合变量的定义union Un un { 0 };struct Stu stu { 0 };//计算联合变量的⼤⼩printf(%d\n, sizeof(un));printf(%d\n, sizeof(stu));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;
}
运行结果 从上述结果我们可以看出代码1的三个地址相同说明成员共用一个地址代码2将i的第四个字节的内容修改为55了那我们就可以画出un的内存图 1.3 相同成员的结构体和联合体的比较
union un
{char c;int i;
};struct s
{char c;int i;
}; 结构体中的每个成员都有自己独立的内存空间各个成员互不干涉同时存在遵循内存对齐原则。因此一个结构体变量的总长度等于所有成员的长度之和。相反联合体的成员共享同一块内存空间同一时间只有一个成员可以使用这块内存。这意味着联合体比结构体在内存使用上更为节约。上篇文章我们介绍了结构体大小的计算我们学会了对齐规则 穿越代码之海探寻结构体深层逻辑展望未来应用新天地-CSDN博客 那联合体的大小怎么计算呢
1.4 联合体大小的计算 1.联合体的大小至少是最大成员的大小。 2.当最大成员的大小不是最大对齐数的整数倍时就需要对齐到最大对齐数的整数倍。 #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;
} Un1最大成员为char[5]占五个字节最大对齐数为45不是4的整数倍所以补3个字节所以大小为8。 Un2最大成员为short[2]占14个字节最大对齐数为4补到16故大小为16。 来看运行结果 使用联合体确实可以节省空间。例如假设我们要搞一个活动并上线一个礼品兑换单。在这个礼品兑换单中有三种商品图书、杯子和衬衫。每种商品都有一些共同的属性如库存量和价格但也有一些与商品类型相关的特定信息。 图书书名、作者、页数 杯子设计 衬衫设计、可选颜色、可选尺寸 如果我们为每种商品单独定义一个结构体那么每个结构体都会占用其所有成员所需的内存空间即使某些成员在某一时刻并不被使用。这样会造成内存的浪费。
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;//尺⼨
};
上述的结构确实设计得相对简单使用起来也很方便。然而这种设计方式包含了所有礼品的各种属性这会导致结构体的大小偏大从而比较浪费内存。因为在礼品兑换单中的商品只有部分属性信息是常用的。
比如如果商品是图书那么就不需要design设计、colors颜色、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;
};
我们可以定义一个包含基础信息的结构体如库存量和价格然后在这个结构体中包含一个联合体该联合体可以存储图书、杯子和衬衫的特定信息。这样我们就可以在一个结构体实例中存储任意一种商品的信息而无需为每种商品都分配完整的内存空间。
通过这种方式使用联合体可以有效地节省空间并提高内存的利用率。
1.5 填坑
在前面的大小端中我们挖了个坑还记得吗 解码新时代内存架构探秘数据在内存中的灵动驻足-CSDN博客 这段代码用来判断机器是大端还是小端。
我们用到了union的特点成员共用一个内存空间。也就意味着我改变i的话c也会跟着改变一个字节。我将i设置为1如果c是0说明是小端反之为大端。
二、枚举
2.1 枚举的声明
枚举顾名思义就是一一列举即把可能的取值一一列举出来。
在现实生活中我们经常会遇到需要枚举的情况。
比如一周的星期一到星期日是有限的7天我们可以一一列举出来。
同样性别有男、女、保密等选项也可以一一列举。
月份有12个也可以进行一一列举。
此外像化学中的三原色也是可以一一列举的。
enum Day//星期
{Mon,Tues,Wed,Thur,Fri,Sat,Sun
};
enum Sex//性别
{MALE,FEMALE,SECRET
};
enum Color//颜⾊
{RED,GREEN,BLUE
};
以上定义的 enum Dayenum Sexenum Color 都是枚举类型。
{} 中的内容是枚举类型的可能取值也被称为枚举常量。
这些可能取值都是有值的默认从0开始依次递增1。当然在声明枚举类型的时候可以赋初值。
enum Color//颜⾊
{RED 2,GREEN 4,BLUE 8
};
2.2 枚举的优点
为什么使用枚举Enumeration 我们可以使用#define来定义常量但为什么还要使用枚举呢 枚举的优点
1. 增加代码的可读性和可维护性枚举提供了一种清晰的方式来表示一组相关的命名整数值。这使得代码更易于理解特别是当这些值具有特定的业务或逻辑意义时。
2. 类型检查与#define定义的标识符相比枚举具有类型检查。这意味着如果你试图将一个枚举类型的变量赋值为一个不属于该枚举类型的值编译器会报错。这有助于防止可能的类型错误。
3. 便于调试预处理阶段会删除#define定义的符号这意味着在调试时这些符号可能不会在调试器中显示。而枚举值则会在调试器中保留这有助于在开发过程中追踪和识别问题。
4. 使用方便一次可以定义多个常量。这减少了重复定义常量的需要并使得代码更加整洁。
5. 遵循作用域规则枚举常量是遵循作用域规则的。这意味着如果你在函数内部声明了一个枚举那么这个枚举只能在该函数内部使用。这有助于限制变量的作用域并防止意外的全局污染。
2.3 枚举的使用
enum Color//颜⾊
{RED 1,GREEN 2,BLUE 4
};
enum Color clr GREEN;//使⽤枚举常量给枚举变量赋值
那是否可以拿整数给枚举变量赋值呢在C语言中是可以的但是在C是不可以的C的类型检查比较严格。 完