目录
1.枚举类型
1.枚举的创建,枚举常量的值
与结构类似,创建的枚举变量可以再声明时直接创建如a1,也可以在后续用enum+定义的类型名来创建变量如a2
enum week
{
Mon,
Tue,
Wes,
Thu,
Fri,
Sat,
Sun
}a1; //不要忘记最后的分号,括号内用逗号隔开,与结构体不同
int main()
{
enum week a2;
return 0;
}
枚举类型的值是可以自己设置的,不设置就是从0开始,Mon是0,Tue是1,以此类型
也可以自己设计,如Mon=1,那Tue就是2,Wes就是3;
或者Mon=4;Wes=7;那Tue是5,Thu是8,以此类推。
2.枚举类型和枚举变量/常量
如上图,枚举类型就是enum week,创建的时候用这个类型定义变量
枚举变量可以修改值,但是枚举常量不可以修改,什么意思?
enum week
{
Mon,
Tue,
Wes,
Thu,
Fri,
Sat,
Sun
}a1; //不要忘记最后的分号,括号内用逗号隔开,与结构体不同
int main()
{
a1=Mon;
a1=9; //?可以这么赋值吗?
return 0;
}
a1就是枚举变量,是可以改变值的,但是Mon,Tue这些事枚举常量,是不可以修改值的
枚举类型在编译器眼里一个单独的类型,
enum week
{
Mon,
Tue,
Wes,
Thu,
Fri,
Sat,
Sun
};
int main()
{
enum week a1 = 0;
return 0;
}
我们创建一个枚举变量a1,赋值0,在c的编译器可以跑,但是在c++上不可以,因为编译器认为0是int型,而a1是枚举类型,两者不等同,但是c编译器默认可以过,c++语法检查严格一些,过不了。
3.与#define定义相比,枚举的好处
我们一一解读
1.代码更好阅读,一大串的0,1,2,3,4和对应的变量名Mon,Tue,Wes,Thu明显后者可读性更好,自然也就更好维护
2.类型上面提到了,如果用#define Mon 1定义 ,在预处理阶段,所有Mon都会被转换成1,也就变成了常数;但是枚举会有类型冲突,如赋值int型会冲突
3.#define出来的宏 和那个全局变量有点类似, 一般都是在全局作用域中的 ,如果两个宏名字给成一样的 ,会出问题;但是枚举不一样,如定义两个枚举变量a1,a2里面都有Mon,这个不会冲突,他们的Mon是更自己的枚举类型挂钩
4.#define定义出来的宏,在预处理阶段会被转换,而我们的调试在调试预处理后的代码
#define M 1000
int main()
{
int a=M;
return 0;
}
这一片代码最后在调试时就是a=1000。
5.定义方便不用多说
2.联合体类型
1.联合体的定义和内存分布
联合体又称共用体,是指多个数据共用一个内存空间,节约空间
union zhiwei
{
char a;
int b;
}u1;
也就是a,b共用一个内存空间,
他们的内存分配如下
2.联合体怎么求占用大小
根据两个原则:
拿上面举例就是 最大成员是int,4字节
char的对齐数是1,vs2019默认是8,取小是1;
int的对齐数是4,取小是4,
因此最大对齐数是4;
最后大小是4的倍数,
所以最后大小是4
关于什么是对齐数,可以参考https://blog.csdn.net/AgoniTop/article/details/123053893
对齐数在结构体中表现明显
3.联合体的应用,巧妙代码
我们都知道一段数据如果占用多个字节,那么存入内存更取出内存都是有顺序的,分为两个顺序:
大端字节存储,小端字节存储;低字节放在低地址,大字节放高地址就是小端存储,反之是大端;
接下来是利用联合体求解存储方式的应用
#include<stdio.h>
int check()
{
union
{
int a;
char b;
}s;
s.a = 1;
return s.b;
}
int main()
{
int ret = check();
if (ret == 1)
printf("小端");
else
printf("大端");
return 0;
}
1在内存中是00 00 00 01,右边是低地址,左边高地址
然后以char的形式拿出来,如果拿01就代表是以低字节取出(取出也遵循大小端,一一对应)
拿出00代表拿的是高字节,意味着存的时候是吧高字节的存储到高地址处。
不同编译器的存放形式不同。