c语言之位域

位域的概念

数据在存储的时候,并不需要占用一个完整的单元,只需要占用一个或者几个二进制位,限定数据的位数,节约内存资源

 简单来说就是,比如一个int,一般来说占用四个字节,那么四个字节就是32个位,但是我们实际当中用到的数据用不了那么多位,比如我们要存储月份,那么月份是不是就是1-12呢,那么我们这个时候就可以把这个int类型设计成四个位,那么它能存储最大的数据就是1111,对吗,也就是0-15的范围,存储2^4个数据,那么这个范围就是我们想要的合理范围。

在c语言中,位域一般用于结构体里面

话不多说,直接上代码

#include 
#include 

struct Data
{
	unsigned int num1 : 1;//1个位 ,二进制为1,也就是只能表示0或者1
	unsigned int num2 : 2;//2个位,二进制为00或者11 0->3 
	unsigned int num3 : 3;//3个位 000 111 0->7
};

void main()
{
	printf("%d\n", sizeof(struct Data));
	system("pause");
}

运行结果:

c语言之位域_第1张图片

后面再来说说怎么计算位域结构体的大小,再说一点就是,位域就相当于是限制了数据大小,不可越界,比如下面的代码

#include 
#include 

struct Data
{
	unsigned int num1 : 1;//1个位 ,二进制为1,也就是只能表示0或者1
	unsigned int num2 : 2;//2个位,二进制为00或者11 0->3 
	unsigned int num3 : 3;//3个位 000 111 0->7
};

void main()
{
	struct Data data1;
	data1.num1 = 2;
	printf("%d\n", data1.num1);
	system("pause");
}

 上面会打印结果:

c语言之位域_第2张图片

一旦越界就不会打印我们想要的结果。

如何判断带有位域的结构体大小

#include 
#include 

union MyUnion1
{
	char bj[5];//5
	int num;
};

union MyUnion2
{
	char bj[5];
	int num[2];
};

struct stu
{
	//联合体的大小就是占用最大的数据类型大小,但必须被最宽基本类型整除
	union{
		char bj[5];
		int bh[2];//
	}class;//8个字节//0 8
	char xm[8];//8 8
	float cj;//16 4 
};//16 + 4 = 20

//这里按照结构体字节对齐来考虑
struct test
{
	char f1 : 3;//0 1
	short f2 : 4;//2 2
	char f3 : 5;//4 1
};//5->6 才是short的整数倍

struct test1
{
	//同类型可以重合
	char num1 : 6;
	char num2 : 3;
	//上面占2个字节
	//下面重合占了四个字节
	int num3 : 5;
	int num5 : 20;//2-》4 + 4 = 8
};//8

struct test2{
	char f1 : 3;//0 1
	char f2;//非位域字段1 1//不用考虑重合
	char f3 : 5;//2 1 ->3
};//3

int main() {
	printf("%d\n", sizeof(struct test));
	printf("%d\n", sizeof(struct test1));
	printf("%d\n",sizeof(struct test2));
	getchar();
	return 0;
}

运行结果:

c语言之位域_第3张图片

如何用位域来读取一个整数、浮点数的二进制位

1.先来看读取一个整数

#include 
#include 


struct bit
{
	unsigned char ch1 : 1;
	unsigned char ch2 : 1;
	unsigned char ch3 : 1;
	unsigned char ch4 : 1;
	unsigned char ch5 : 1;
	unsigned char ch6 : 1;
	unsigned char ch7 : 1;
	unsigned char ch8 : 1;
};//数据类型相同占用重合1个字节,刚好八个位

void main()
{
	int num = 2;
	struct bit *p = #//指向int类型的首地址
	int length = 4;//int占四个字节,也就是4
	//4 3 2 1
	while (length--) {
		//注意,数据从右往左解析的
		printf("%d%d%d%d %d%d%d%d ",
			(p + length)->ch8,
			(p + length)->ch7,
			(p + length)->ch6,
			(p + length)->ch5,
			(p + length)->ch4,
			(p + length)->ch3,
			(p + length)->ch2,
			(p + length)->ch1);
	}
	system("pause");
}

运行结果

c语言之位域_第4张图片

 2.再来看一个浮点数的读取

#include 
#include 


struct bit
{
	unsigned char ch1 : 1;
	unsigned char ch2 : 1;
	unsigned char ch3 : 1;
	unsigned char ch4 : 1;
	unsigned char ch5 : 1;
	unsigned char ch6 : 1;
	unsigned char ch7 : 1;
	unsigned char ch8 : 1;
};//数据类型相同占用重合1个字节,刚好八个位

void main()
{
	float num = 19.625f;
	struct bit *p = #//指向int类型的首地址

	int length = 4;
	//4 3 2 1
	while (length--) {
		printf("%d%d%d%d %d%d%d%d ",
			(p + length)->ch8,
			(p + length)->ch7,
			(p + length)->ch6,
			(p + length)->ch5,
			(p + length)->ch4,
			(p + length)->ch3,
			(p + length)->ch2,
			(p + length)->ch1);
	}

	printf("%p\n", p);

	system("pause");
}

运行结果:

c语言之位域_第5张图片

看一下浮点数内存图 

c语言之位域_第6张图片 

 

你可能感兴趣的:(c编程,c语言,位域,结构体大小)