引言:
C语言分为:1、内置类型
2、自定义类型: 1》结构体——每个成员有自己的空间
2》枚举型——定义多个常量
3》联合体——所有成员共用一快内存空间
一、结构体:
单独写过了一篇 关于结构体的介绍以及使用
二、 枚举型:
所谓的枚举:就是一一例举,里面的内容为常量,把可能得值例举出来,比如周一到周日是七天,可以通过枚举来一一例举出来
类型建立:
enum 为枚举的关键词,下图关于枚举类型的申明:(注意我只写到了周六)
默认是从0开始 因此各个常量从上到下依次为 0 1 2 3 4 5 6 我们会从中多选一,这些 数值都被赋予了名称,比如:0的名称就是Mon;
枚举变量创建和命名空间
下面就是枚举型变量申明,第二个Day标识符为变量名
变量名是可以随便取名的,但是我用了与枚举型的名称相同的部分,是想说下 命名空间
变量名和类型名是属于不同的命名空间,他们的性质不同的 一个地名 一个姓名 区别就出来了:
所以相同的名字,不同的性质,即使名称相同,也不会有影响(相互独立)
枚举的“=”符:
在枚举中,枚举常量可以用赋值运算符进行赋值,给一个定值,那么没有给定 定值的,枚举常量会根据前一个枚举常量给自己默认一个定值,即:前一个常量的定值+1
注意:多个枚举常量允许定值是同一个值
如:我给Tues = 0,此时Mon默认会为 0,这种情况也是被允许的
使用:
如下:
enum Day
{Mon=1,Tues,wed,Thur,Fri,Sat,Sun};int main()
{enum Day Day;do {scanf("%d",&Day);if (Day > 7){printf("输入错误!!\n");}switch (Day){case Mon:printf("周一\n");break;case Tues:printf("周二\n");break;case wed:printf("周三\n");break;case Thur:printf("周四\n");break;case Fri:printf("周五\n");break;case Sat:printf("周六\n");break;case Sun:printf("周日\n");break;default:break;}} while (Day > 0);return 0;
}
优点:
1、可读性提升
2、于#define相比,有类型的检查,更加严谨
3、便于调试,预处理阶段会删除#define定义的符号
4、使用方便,一次可以定义多个常量
5、枚举遵循作用域,声明在函数中,只能在该函数中使用
补充:
可以在枚举常量例举完以后加一个 lnvalid(无效的)
三、联合体(共同体) :
类型建立:
和前面的自定义类型都是一个样:union为关键字
声明:
区别:和结构体有点类似,但是又不同,独特在于 他的成员共用一块空间,这样的话也就是每次使用时只能用一个成员,而结构体的话却是所有成员都能使用
创建联合体变量:同理和上述自定义类型的建立是一样的,不做赘述了
联合体的变量大小计算:
联合体特点:给联合体一个成员赋值,另一个成员的值也会跟着变化
根据这一特点,那么我们计算它的变量大小,是不是要考虑到:它的大小至少是最大成员的大小,不然最大成员都保存不了,那不就是一个没有用的“东西”!
用sizeof计算其大小,如下:
在这里:用到了之前结构体中的内存对齐这个知识点,最大的int型为4个字节,VS中默认对齐数是 8 ,那么对于int 型的对齐数为 4(最大对齐数也是4) 所以申请的内存大小如下:
但是,还有一种情况,最大成员大小的不是最大对齐数的整数倍时,就要创建到最大对齐数的整数倍
如下 8为最大对齐数的整数倍
我们是根据成员类型来确定对齐数的,所以虽然数组char型有5个元素,说明需要5个字节,但是不影响我们的对齐数,找整数倍也要找到合适的,因为要2成员中任意成员都能用上
实用性:
假设商场有一个礼品清单:你去抽奖,只能中一个属性的商品,此时是不是就能用到联合体,商品的本身属性用联合体来描写,比起直接全部用联合体,节省了不少空间
计算改编译器是大小端字节的哪一种:
VS中是小端 不懂大小端的可以看 ->大小端序列存储
这里传1比较好,若是传别的数会容易发生,因为char的大小为1字节,int大小为4字节;传1
的话就是00 00 00 01(方便观察,以16进制呈现),若是小端排序 则为01 00 00 00,char型占一个字节,将后面的00 00 00
截掉了,传其他数的话截取得到的数比较麻烦