位段
在结构体中,以位为单位的成员,咱们称之为位段(位域)。
struct packed_data{
	unsigned int a:2;
	unsigned int b:6;
	unsigned int c:4;
	unsigned int d:4;
	unsigned int i;
} data;

 注意:不能对位段成员取地址。
#include<stdio.h>
struct packed_data{
	unsigned int a:2;
	unsigned int b:6;
	unsigned int c:4;
	unsigned int d:4;
	unsigned int i;
} data;
int main()
{
	printf("%d\n",sizeof(data));
	printf("%p\n",&data);
	printf("%p\n",&(data.i));
	return 0;
}
位段注意:
- 对于位段成员的引用如下:
data.a =2
赋值时,不要超出位段定义的范围;
 如段成员a定义为2位,最大值为3,即(11)2
 所以如果data.a =5,就会取5的低两位进行赋值 101
- 位段成员的类型必须指定为整形或字符型
- 一个位段必须存放在一个存储单元中,不能跨两个单元。
 第一个单元空间不能容纳下一个位段,则该空间不用,而从下一个单元起存放该位段。
位段的存储单元:
- char型位段 存储单元是1个字节
- short int型的位段存储单元是2个字节
- int的位段,存储单元是4字节
- long int的位段,存储单元是4字节
struct stu{
	char a:7;
	char b:7;
	char c:2;
}temp;//占3字节,b不能跨 存储单元存储
#include<stdio.h>
struct stu{
	char a:7;
	char b:7;
	char c:2;
}temp;
int main()
{
	printf("%d\n",sizeof(temp));
	return 0;
}
//结果为:3 ,证明位段不能跨其存储单元存储
注意:不能取 temp.b的地址,因为b可能不够1字节,不能取地址。
位段的长度不能大于存储单元的长度
- char型位段不能大于8位
- short int型位段不能大于16位
- int的位段,位段不能大于32位
- long int的位段,位段不能大于32位
#include<stdio.h>
struct stu{
	char a:9;
	char b:7;
	char c:2;
}temp;
int main()
{
	printf("%d\n",sizeof(temp));
	return 0;
}
//分析:编译出错,位段a不能大于其存储单元的大小
如一个段要从另一个存储单元开始,可以定义
unsigned char a:1;
unsigned char b:2;
unsigned char :0;
unsigned char c:3; //(另一个单元)
由于用了长度为0的位段,其作用是使下一个位段从下一个存储单元开始存放。
 将a、b存储在一个存储单元中,c另存在下一个单元。
#include<stdio.h>
struct m_type{
	unsigned char a:1;
	unsigned char b:2;
	unsigned char :0;
	unsigned char c:3;
};
int main()
{
	struct m_type temp;
	printf("%d\n",sizeof(temp));
	return 0;
}
可以定义无意义位段,如:
unsigned a: 1;
unsigned : 2;
unsigned b: 3;
struct data{
	char a:1;
	char b:1;
	char c:1;
	char d:1;
	char e:1;
	char f:1;
	char g:1;
	char h:1;
}temp;
int main()
{
	char p0;
	//p0=0x01;// 0000 0001
	temp.a=1;
	//p0=temp;//错的,类型不匹配
	//p0=(char)temp;//错的,编译器不允许将结构体变量,强制转成基本类型的。
	p0 = *((char *)(&temp));
}









![[山海关crypto 训练营 day10]](https://img-blog.csdnimg.cn/136bc9e3f6f14ffc9d1f7e06048871c9.png)









