本章内容
- 位段
- 枚举
- 联合
什么是位段
位段的声明和结构是类似的,有两个不同。
1.位段的成员必须是int、unsigned int或signed int
2.位段的成员名后边。边有一个冒号和一个数字。
比如:
struct A
{
int a :2; //2表示a占2个bit位
int b :5; //5表示b占5个bit位
int c :10;
int d :30;
};
//A就是一个位段
#include<stdio.h>
struct S
{
int a :2; //2表示a占2个bit位
int b :5; //5表示b占5个bit位
int c :10;
int d :30;
};
//2+5+10+30=47bit-6个字节*8=48bit
int main()
{
struct S s;
printf("%d\n",sizeof(s));
}
int a :2; //2 表示 占a的2个bit位, 而a占4个字节因为int型(4*8=32位)
.....
运行结果:
图解:
位段的内存分配
1.位段的成员可以是int 、unsigned int 、signed int或者char(属于整型家族)类型,
2.位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式开辟的。
3.位段涉及很多不确定因素。位段是不跨平台的。注重可移植的程序应该避免使用位段。
位段的跨平台问题
1.int位段被当成有符号数还是无符号数是不确定的
2.位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题
3.位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
4.当一个结构包含两个位段,第二个位段成员比较大,无法容纳第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。
总结
跟结构相比,位段可以达到同样的效果,但是可以很好节省空间。但是有跨平台问题的存在。
枚举
枚举顾名思义就是列举。
把可能的取值列举出来。
比如我们现实生活中:
一周的星期一到星期日是有限的七天,可以列举
性别,有男、女、保密,也可以列举
月份有12个月也可以列举。
这里就可以使用枚举了。
枚举的类型的定义
#include<stdio.h>
//定义枚举类型
enum Sex
{
//枚举的可能取值--枚举常量
male, //0 枚举成员默认从零开始
female, //1
secret //2
};
枚举的使用
#include<stdio.h>
//定义枚举类型
enum Sex
{
//枚举的可能取值--枚举常量
male, //0 枚举成员默认从零开始
female, //1
secret //2
};
int main()
{
enum Sex s = male; //定义一个枚举变量
s = female; //枚举的赋值
//取值只能取枚举里面定义的变量
printf("%d %d %d\n",male,female,secret);
return 0;
}
运行结果
运行结果:
c语言的源代码-->预编译---> 编译--->可执行文件
枚举的优点
为什么使用枚举
我们可以使用#define定义常量,为什么非要使用枚举,枚举的优点
1.增加代码的可读性和可维护性
2.和#define定义的标识符比较枚举有类型检查,更加严谨。
3.防止了命名污染(封装)
4.便于调试
5.使用方便。一次可以定义多个常量。
联合(共用体、联合体)
联合也是一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员。特点是这些成员共用同一块空间,所以联合也叫共用体。
比如:
联合的特点
联合的成员是共用同一块内存空间的,这样一个联合变量大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。
题目:
判断当前计算机的大小端存储
int main()
{
int a=0x11223344;
//低地址..................高地址
//...[][][][][11][22][33][44][][][]...........大端字节序存储模式
//...[][][][][44][33][22][11][][][]...........小端字节序存储模式
//
};
源码实现:
//2.判断当前计算机的大小端存储
#include<stdio.h>
int check_sys()
{
union Un
{
char c ;
int i;
}u;
u.i =1;
//返回1,表示小端
//返回0,表示大端
return 0;
}
int main()
{
int a = 1;
int ret =check_sys();
if (1==ret)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
运行结果:
联合大小的计算
- 联合大小至少是最大成员的大小
- 当最大成员的大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍
案例:
对于数组算对齐数的时候是指元素的对齐数,不是整个元素怎么样
所以下面这个案例
最大成员是数组arr【5】,而5不是最大对齐数(4)的整数倍,
所以就要对齐到最大对齐数的整数倍
4*2=8