cppTest-4.1:位域

/**
 * cppTest-4.1:位域
 *
 *参考了百度百科的资料后,终于搞清楚了位域的问题!!!
 *这个例子涉及到了位域的基本特性、符号特性、对齐规则、大小计算、空域、无名位域等问题。
 *
 *所谓“位域”是把一个字节中的二进位划分为几个不同的区域, 并说明每个区域的位数。
 * 每个域有一个域名,允许在程序中按域名进行操作。
 * 这样就可以把几个不同的对象用一个字节的二进制位域来表示。
 * author 炜sama
 */
#include<stdio.h>
#include<iostream.h>

int main(){

	cout<<"位域的一般情况"<<endl;
	struct bf0{ 
		unsigned a:1;
		unsigned b:3;
		unsigned c:4;
		//double d:1;//错误!位域只能是有序数据类型!(char,short,int,long)
		//unsigned e:33;//错误!定义时委员宽度不能超过unsigned的类型长度!
	}bit,*pbit;
	bit.a=1;
	bit.b=7;
	bit.b=18;//赋值时超过位域长度的部分自动截掉
	bit.c=15;
	//位域里的数据可以按任意类型输出
	printf("%d,%d,%d\n",bit.a,bit.b,bit.c); 
	pbit=&bit;
	pbit-> a=0;
	pbit-> b&=3;
	pbit-> c|=1;
	printf("%d,%d,%d\n",pbit->a,pbit->b,pbit->c); 
	
	cout<<"位域符号问题"<<endl;
	struct bf02{
		int a:1;
		int b:2;
		int c:13;
	};
	bf02 b02;
	b02.a=(int)1;
	b02.b=(int)2;
	b02.c=(int)3;
	cout<<b02.a<<","<<b02.b<<","<<b02.c<<endl;//结果是-1,-2,3 !!!而不是1,2,3!!!
	//原因:有符号数在机器中是以补码的形式存在的,其正负的判断有其规则。
	//位域是以原码的形式来进行操作的,这中间有差异,造成了上面的结果。
	//而关于位域的正负数判断,也不是简单的首bit的0或1来决定,否则上面的结果就应该是-1 -2 -3或者1 2 3了。
	//位域的实现,是编译器相关的。建议是,使用位域不要使用正负这样的特性,即最好是使用如下的unsigned:

	struct bf03{
		unsigned a:1;                            
		unsigned b:2;                            
		unsigned c:13;                           
	};                                        
	bf03 b03;                                 
	b03.a=(unsigned)1;                        
	b03.b=(unsigned)2;                        
	b03.c=(unsigned)3;                        
	cout<<b03.a<<","<<b03.b<<","<<b03.c<<endl;//1,2,3
	
	cout<<"如果相邻位域字段的类型相同,且其位宽之和<=类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止"<<endl;
	struct bf1{
		//char类型大小为8位
		char a:1;
		char b:2;
		char c:5;
	};
	cout<<sizeof(bf1)<<endl;//1
	
	struct bf12{
		//int类型大小为32位
		int a:8;
		int b:8;
		int c:8;
		int d:1;
	};
	cout<<sizeof(bf12)<<endl;//4

	cout<<"如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍"<<endl;
	struct bf2{
		//char类型大小为8位
		char a:1;
		char b:2;
		char c:5;
		char d:1;
	};
	cout<<sizeof(bf2)<<endl;//2

	struct bf22{
		//int类型大小为32位
		int a:8;
		int b:8;
		int c:8;
		int d:9;
	};
	cout<<sizeof(bf22)<<endl;//8

	cout<<"如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式(不同位域字段存放在不同的位域类型字节中),Dev-C++和GCC都采取压缩方式"<<endl;
	struct bf3{
		char a:1;
		char b:2;
		char c:5;
		int d:1;
	};
	cout<<sizeof(bf3)<<endl;//8

	struct bf32{
		char a:1;
		int d:1;
	};
	cout<<sizeof(bf32)<<endl;//8

	struct bf33{
		int d:1;
		char a:1;
	};
	cout<<sizeof(bf33)<<endl;//8
	
	struct bf34{
		int d:1;
		//char a:1;
		short s:1;//short的长度为2字节!
		long l:1;//在这里long型为4字节长度!!!
	};
	cout<<sizeof(bf34)<<endl;//12
		
	struct bf342{
		int i:1;
		long l:1;//在这里long型为4字节长度!!!
		int i2:1;
	};
	cout<<sizeof(bf342)<<endl;//4!long的长度与int的一样,所以结果是4而不是12!看来是根据数据类型长度来对齐的而不是数据类型类别!
		
	struct bf35{
		char c0:8;
		int i:32;
		char c1:8;
		char c2:8;
		//double d:1;//错误!位域只能是有序数据类型!!!
	};
	cout<<sizeof(bf35)<<endl;//12。注意与bf3的区别!

	struct bf36{
		char c0:8;
		int i:32;
		char c1:8;
		char c2:8;
		char c3:7;
		char c4:2;
		char c5:8;
		int i2:1;
		int i3:1;
	};	
	cout<<sizeof(bf36)<<endl;//20。注意与bf35、bf3的区别!

	//到这里已经可以推断出位域在vc6里的排放规则了!:
	//1、以长度最长的数据类型的大小为对齐大小l(形象地把它想象成一行数组);
	//2、相同类型的位域才能排在同一行,如果l不够放,那剩下的另起一行排放;
	//3、如果有另外不同类型的位域插入,那这个不同的位域要另起一行排放,而不是接着排在之前的l里;
	//4、最后算出来的sizeof一定是l的倍数!

	cout<<"空域问题"<<endl;
	struct bfk1{
		char a:1;
		char :0;//空域的定义格式
	};
	cout<<sizeof(bfk1)<<endl;//结果是1!!!
	
	struct bfk13{
		char c:1;
		char :0;//空域的定义格式
		char c1:1;
	};
	cout<<sizeof(bfk13)<<endl;//结果是2!!!
	
	struct bfk14{
		char c:8;
		char :0;//空域的定义格式
	};
	cout<<sizeof(bfk14)<<endl;//结果是1!!!
	
	struct bfk15{
		char c:8;
		char :0;//空域的定义格式
		char :0;//空域的定义格式
		char :0;//空域的定义格式
		int i:1;
	};
	cout<<sizeof(bfk15)<<endl;//结果是8!!!
	
	struct bfk16{
		char :0;//空域的定义格式
		int i:31;
		int i2:1;
		char c:8;
	};
	cout<<sizeof(bfk16)<<endl;//结果是8!!!
	
	struct bfk17{
		char c:8;
		int :0;//空域的定义格式
	};
	cout<<sizeof(bfk17)<<endl;//结果是4!!!

	//到这里这里可以总结出vc6里空域的占位规则了:
	//对齐规则与一般情况下一样,不同的是——
	//1、空域放在最前和最后时,不占位;
	//2、空域放在中间时,如果有连续n个空域,那会合并为一个空域;
	//3、空域会补齐当前“行”的空位;
	//4、空域的类型无关紧要,唯一的作用是是否可以决定最长“行长度”l。例如bfk17的情况。
	
	cout<<"无名位域问题"<<endl;
	struct bfw1{
		char a:1;
		char :8;//无名位域的定义格式
	};
	cout<<sizeof(bfw1)<<endl;//结果是2!!!
	
	struct bfw2{
		char a:1;
		int :8;//无名位域的定义格式
		int :32;//无名位域的定义格式
	};
	cout<<sizeof(bfw2)<<endl;//结果是12!!!

	struct bfw3{
		int :8;//无名位域的定义格式
		char a:1;
		int :32;//无名位域的定义格式
	};
	cout<<sizeof(bfw3)<<endl;//结果是12!!!
	
	//无名域的占位情况与空域很相似

	return 0;
}

这个错误的原因是在运行"./Log4cppTest"时,系统无法找到共享库"liblog4cpp.so.5",导致无法打开共享对象文件。 解决这个问题的方法是确保"liblog4cpp.so.5"库文件存在于系统的共享库路径中,并且路径已正确配置。您可以通过以下步骤来解决这个问题: 1. 首先,确认您已经安装了"liblog4cpp.so.5"库文件。您可以在终端中使用以下命令来查找该文件: ``` $ find / -name liblog4cpp.so.5 ``` 如果该文件存在,则会返回文件的路径。如果不存在,您需要下载并安装该库文件。 2. 一旦确认库文件存在,您需要将其路径添加到系统的共享库路径中。可以通过以下命令将库文件路径添加到/etc/ld.so.conf文件中: ``` $ sudo echo "/path/to/liblog4cpp.so.5" >> /etc/ld.so.conf ``` 请将"/path/to/liblog4cpp.so.5"替换为实际的库文件路径。 3. 更新共享库缓存,使系统能够找到新添加的库文件路径: ``` $ sudo ldconfig ``` 现在,您应该可以成功运行"./Log4cppTest",而不再出现"error while loading shared libraries: liblog4cpp.so.5: cannot open shared object file: No such file or directory"的错误信息了。请按照上述步骤进行操作,确保路径和命令的准确性。<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [VS code出现错误:g++.exe: error: Hello: No such file or directory g++.exe: error: Word.cpp: No such ...](https://blog.csdn.net/qq_45708377/article/details/112732294)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [cpptest:C++学习笔记 包括 侯捷讲解的系列CPP课程以及UNP、APUE等](https://download.csdn.net/download/weixin_42122306/19205361)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值