位段
位段(成员必须是整型) char也属于整型家族
struct S
{
int _a : 2;//**代表a占两个字节,一个字节八个比特位**
int _b : 5;
int _c : 10;
int _d : 30;
};
int main()
{
printf("%d\n", sizeof(struct S));
system("pause");
return 0;
}
位段的内存分配
1.位段的成员可以是int,unsigned int或者signed int或者是char(属于整型家族)类型
2.位段的空间上是需要以4个字节(int)或者1个字节(char)的方式来开辟的
3.位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段
struct S
{
char a : 3;
char b : 4;
char c : 5;
char d : 4;
};
int main()
{
struct S s = { 0 }; //very important!!!
//printf("%d\n", sizeof(struct S));//3
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;
return 0;
}
枚举
标题和define的区别 #define 不能调试
enum Day
{
Mon = 1,//0
Tues,//1
Wed,//2
Thur,
Fri,
Sat,
Sun
};
int main()
{
enum Day day = Mon;**//初始化只能赋已有成员**
day = Tues;
printf("%d\n", Mon);
printf("%d\n", Tues);
printf("%d\n", Wed);
printf("%d\n", Thur);
return 0;
}
1.为什么要用枚举替换#define
(1)增加代码的可读性和可维护性
(2)和#define定义的标识符比较枚举有类型检查,更加严谨
(3)防止了命名污染
(4)便于调试,#define不可调试
(6)使用方便,一次可以定义多个常量
联合
union Un
{
char i;//**成员共用一个空间**
int c;
double d;
};
int main()
{
union Un u = { 0 };
printf("%d\n", sizeof(union Un));//8
printf("%p\n", &(u.c));
printf("%p\n", &(u.i));
printf("%p\n", &(u.d));
return 0;
}
判断机器的大小端
普通方式
int check_sys()
{
int a = 1;
return *(char*)&a;
}
int main()
{
int ret = check_sys();
if (ret == 1)
{
printf("小端");
}
else
printf("大端");
return 0;
}
联合的方式判断
int check_sys()
{
union Un
{
char c;
int i;
}u;
u.i = 1;
**//返回1,小端
//返回0,大端**
return u.c;//**取出第一个字节,类似于普通方法**
}
int main()
{
int ret = check_sys();
if (ret == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
求联合的大小
union Un
{
char c;
int i;
};
union Un2
{
short c[7];//short两个字节
int i;
};
int main()
{
printf("%d\n", sizeof(union Un));//8
printf("%d\n", sizeof(union Un2));//16
return 0;
}
(1)联合存在对齐
(2)联合的大小至少是最大成员的大小
(3)当最大成员不是最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍处