1.枚举
枚举就是把有可能得值一一列举出来exp:人的性别,一个星期的天数,
枚举像结构体一样,也是一种类型,叫枚举类型,先定义一个枚举类型
#includeenum Sex//这就是一种枚据类型的定义 { male, female }; int main() { return 0; ]
而在没给这些枚举常量成员赋初始值时,它们有默认的值从上到下,依次位0,1,2.....
而我们要是给其中一个再类型里就给他定义了初始值,那么其之后的成员依次按照这个成员的值加一exp:
#includeenum Color { red, yellow=4, blue }; int main() { blue=3;//error enum Color c=2;//error,其左边是枚举类型,右边是int类型,但那是在有编译器上会忽略这一点依然能跑 enum Color r=blue; return 0; ]
这时的red还是等于0而blue是5,而且一旦再定义里初始化后不能再在函数体里改变他的值,毕竟枚举成员是常量,就像#define定义过的常量一样,不能再进行修改,一般的枚举使用,将枚举常量的值赋给枚举类型变量
枚举的优点:
增加了代码的可读性,枚举有具体的类型;
#define定义的变量名其实类似一种符号,遇到相同的符号就会替换,在预编译的时候进行;
枚举的成员名都放在类型框里,不会和其他的变量名起冲突;
2.联合(共用体)
联合也是一种自定义类型,其特征是成员共用一块内存空间
#includeunion Un { int a; char b; }u; int main() { printf("%d",sizeof(u));//4,,当对a和b取地址时,发现他们的结果是一样的 return 0; }
判断机器大小端:
#include//int cheak(int* p) //{ // return *(char*)p;//这里我们只想知道存在内存开头的第一个字节不是01就行了,内存窗口是按照十六进 // 制 //从左向右地址由低到高,在vs里.是一的话就是小端,反之为大端 //} int cheak() { union Un { char c; int i; }u; u.i=1 return u.c;//结果一样,因为联合体的成员使用公共的内存空间 } int main() { int a=1; if(cheak(&a)==1) printf("小端n");//vs里输出小端 else printf("大端n"); return 0; }
此处其实联合体的访问成员的方法和结构体一样,就是它们的内存排列是不同的
同样的也有匿名联合体
下面涉及到联合体和枚举等自定义类型的空间大小:
联合体的大小,至少是最大成员的空间的大小
当最大成员的大小不是最大对齐数整数倍时,要对齐到最大对齐数的整数倍处
#includeunion U { char a; int i; }; union Un { char a;//对齐数为1 char str[5];//对齐数为每个元素和系统默认对齐数1、8比较,较小的是对齐数为1 int i;//对齐数为4 }; struct T { char a; int i; }; enum En { red, yellow, blue }; int main() { union U u; union Un n; struct T t; enum En e = red; printf("%dn",sizeof(t));//8//这里的求结构体,枚举,联合体的大小时都是先通过类型去创建量, //然后再求这个变量的 printf("%dn", sizeof(u));//4//最小是最大成员的空间大小 printf("%dn", sizeof(e));//4//枚举类型的大小是因着枚举常量最大所占空间(red等于0;是个整 //型,所以最大的空间是整形大小)改变的,最大可以到longlong printf("%dn", sizeof(n));//8一个整型的共用空间显然放不下char str[5],所以得另开辟一块最大 //对齐数整数倍的空间,刚好可以放下,所以联合体变量n的大小为8 return 0;
联合体也需要对齐



