在结构体中,以位为单位的成员,咱们称之为位段、位域
struct test {
unsigned int a : 2; //a只占2位
unsigned int b : 6; //b占6位
unsigned int c : 4;
unsigned int d : 4;
unsigned int i;
}data;
不能对位段成员取地址,因为可能不够一个字节

printf("%d\n", sizeof(data));
printf("%p\n", &data);
printf("%p\n", &(data.i)); //与data相差4个字节
赋值时,不要超出位段定义的范围:
如段成员a定义为2位,最大值为3.即(11)2 所以data.a=5,就会取5的低两位进行赋值 101
data.a = 2;
printf("%d\n", data.a);
data.a = 5; //101
printf("%d\n", data.a); //实际01
位段的成员必须为整型或者字符型
一个位段必须存放在一个存储单元中,不能跨两个单元第一个单元空间不能容纳下一个位段,则该空间不用,而从下一个单元起存放该位段
位段的存储单元:
(1):char型位段 存储单元是1个字节
(2):short int 型的位段存储单元是2个字节
(3):int的位段存储单元是4字节
(4):long int 的位段存储单元是4字节
struct stu {
char a:7;
char b:7;
char e: 2:
}temp;
//占3字节,b不能跨 存储单元存储
位段的长度不能大于存储单元的长度
(1):char 型位段不能大于8位
(2):short int 型位段不能大于 16 位
(3):int 的位段,位段不能大于 32 位
(4):long int 的位段,位段不能大于32位
如一个段要从另一个存储单元开始。可以定义:
usigned char a: 1;
unsigned char b:2;
unsigned char :0;
unsigned char c:3;(另一个单元)
由于用了长度为0的位段,其作用是使下一个位段从下一个存储单元开始存放将a、b存储在一个存储单元中,c另存在下一个单元
可以定义无意义位段,如:
unsigned a: 1;
unsigned : 2; //浪费了2位不用
unsigned b: 3
共用体
共用体和结构体类似,也是一种构造类型的数据结构
在进行某些算法的时候,需要使几种不同类型的变量存到同一段内存单元中,几个变量所使用空间相互重叠
这种几个不同的变量共同占用一段内存的结构,在C语言中,被称作“共用体”类型结构
共用体所有成员占有同一段地址空间
共用体的大小是其占内存长度最大的成员的大小
定义共用体类型的方法和结构体非常相似,把struct改成union 就可以了
typedef union uni{
char a;
int b;
short int c;
}Uni;
void func2_2() {
Uni t1;
printf("%d\n", sizeof(t1)); //4字节
printf("%p\n", &(t1.a));
printf("%p\n", &(t1.b));
printf("%p\n", &(t1.c)); //地址相同
}
共用体的特点:
1、同一内存段可以用来存放几种不同类型的成员,但每一瞬时只有一种起作用
2、共用体变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后原有的成员的值会被覆盖
3、共用体变量的地址和它的各成员的地址都是同一地址
4、共用体变量的初始化union data a={123}:初始化共用体只能为第一个成员赋值,不能给所有成员都赋初值
t1.b = 0xaaaaccab;
printf("%x\n", (t1.b));
printf("%x\n", (t1.a));
t1.a = 0xdd;
printf("%x\n", (t1.b));
printf("%d\n", sizeof(t1));