1.枚举
枚举就是把有可能得值一一列举出来exp:人的性别,一个星期的天数,
枚举像结构体一样,也是一种类型,叫枚举类型,先定义一个枚举类型
#include <stdio.h>
enum Sex//这就是一种枚据类型的定义
{
male,
female
};
int main()
{
return 0;
]
而在没给这些枚举常量成员赋初始值时,它们有默认的值从上到下,依次位0,1,2.....
而我们要是给其中一个再类型里就给他定义了初始值,那么其之后的成员依次按照这个成员的值加一exp:
#include <stdio.h>
enum 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.联合(共用体)
联合也是一种自定义类型,其特征是成员共用一块内存空间
#include <stdio.h>
union Un
{
int a;
char b;
}u;
int main()
{
printf("%d",sizeof(u));//4,,当对a和b取地址时,发现他们的结果是一样的
return 0;
}
判断机器大小端:
#include <stdio.h>
//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;
}
此处其实联合体的访问成员的方法和结构体一样,就是它们的内存排列是不同的
同样的也有匿名联合体
下面涉及到联合体和枚举等自定义类型的空间大小:
联合体的大小,至少是最大成员的空间的大小
当最大成员的大小不是最大对齐数整数倍时,要对齐到最大对齐数的整数倍处
#include <stdio.h>
union 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("%d\n",sizeof(t));//8//这里的求结构体,枚举,联合体的大小时都是先通过类型去创建量, //然后再求这个变量的
printf("%d\n", sizeof(u));//4//最小是最大成员的整数倍的空间大小
printf("%d\n", sizeof(e));//4//枚举类型的大小是因着枚举常量最大所占空间(red等于0;是个整 //型,所以最大的空间是整形大小)改变的,最大可以到longlong
printf("%d\n", sizeof(n));//8一个整型的共用空间显然放不下char str[5],所以得另开辟一块最大 //对齐数整数倍的空间,刚好可以放下,所以联合体变量n的大小为8
return 0;
联合体也需要对齐