C/C++,位域问题
typedefstructAA{intb1:5;intb2:2;}AA;AAaa;int*bb=(int*)(&aa);*bb=0xD5;//11010101cout<<...
typedef struct AA
{
int b1:5;
int b2:2;
}AA;
AA aa;
int *bb = (int*)(&aa);
*bb = 0xD5;//11010101
cout << aa.b1 <<endl; //为什么打印-11
cout << aa.b2 <<endl; //为什么打印-2 展开
{
int b1:5;
int b2:2;
}AA;
AA aa;
int *bb = (int*)(&aa);
*bb = 0xD5;//11010101
cout << aa.b1 <<endl; //为什么打印-11
cout << aa.b2 <<endl; //为什么打印-2 展开
2个回答
展开全部
位段(bit-field)是以位为单位来定义结构体(或联合体)中的成员变量所占的空间。
含有位段的结构体(联合体)称为位段结构。采用位段结构既能够节省空间,又方便于操作。
你的做法类似于用联合体来给位段结构赋值,位段在内存中的存储只有编译器(或写编译器的人)才最清楚,而且这和机器有关(大小端机器:百度上查一下可看详细内容)。从你的程序运行结果来看,b1占了一个字节的低5位,b2占了该字节的后续两位。
0xD5是一个整数,一般整数常数占四个字节(32位机),这个数值完整数据应该是:0000 0000 0000 0000 0000 0000 1101 0101。
你可试一下,sizeof(aa)=4,即aa占四个字节,b1,b2在第一个字节里(这从你的测试结果中能看出来,而且b1=1 0101 b2=10,为什么这样?这是由你的机器和编译器决定的)。
以上,说清了b1 b2中存的内容,为什么会是-11和-2,楼上已经解释了,可以那样理解。(这里又涉及到补码的知识:计算机中存储整数时,是按补码存储的。关于原码、反码、补码请查相关知识)
研究为什么输出-11 -2其实没有意义。
想想,我们用位段的原因是什么?是为了用最少的内存来表示足够的数据。如:性别,只分两种,用一个整数来表示有嫌浪费,只用一个bit(0,1)就可以了。再如:四季,春夏秋冬,只有四种,用两个bit就可以了(00,01,10.,11)。
为什么要节省内存?一是以前内存很小,程序员为了更有效的利用资源(由于内存的进步,现在的应用系统开发,基本不考虑这个了)。二是特种行业开发,其应用内存小(或有其它原因),如:单片机开发,对这种应用很有必要。用时,只是为了用最少的资源表示出足够的数据形式。不是输出来让人看的,主要是完成相应的条件控制等。输出此类数据一般用于调试,因此,如果输出这类数据,最好以16进制方式输出,为的是看清楚这个内存里存的是什么,而不是是多少。
说了许多,纯属个人见解,希望对你有帮助。
含有位段的结构体(联合体)称为位段结构。采用位段结构既能够节省空间,又方便于操作。
你的做法类似于用联合体来给位段结构赋值,位段在内存中的存储只有编译器(或写编译器的人)才最清楚,而且这和机器有关(大小端机器:百度上查一下可看详细内容)。从你的程序运行结果来看,b1占了一个字节的低5位,b2占了该字节的后续两位。
0xD5是一个整数,一般整数常数占四个字节(32位机),这个数值完整数据应该是:0000 0000 0000 0000 0000 0000 1101 0101。
你可试一下,sizeof(aa)=4,即aa占四个字节,b1,b2在第一个字节里(这从你的测试结果中能看出来,而且b1=1 0101 b2=10,为什么这样?这是由你的机器和编译器决定的)。
以上,说清了b1 b2中存的内容,为什么会是-11和-2,楼上已经解释了,可以那样理解。(这里又涉及到补码的知识:计算机中存储整数时,是按补码存储的。关于原码、反码、补码请查相关知识)
研究为什么输出-11 -2其实没有意义。
想想,我们用位段的原因是什么?是为了用最少的内存来表示足够的数据。如:性别,只分两种,用一个整数来表示有嫌浪费,只用一个bit(0,1)就可以了。再如:四季,春夏秋冬,只有四种,用两个bit就可以了(00,01,10.,11)。
为什么要节省内存?一是以前内存很小,程序员为了更有效的利用资源(由于内存的进步,现在的应用系统开发,基本不考虑这个了)。二是特种行业开发,其应用内存小(或有其它原因),如:单片机开发,对这种应用很有必要。用时,只是为了用最少的资源表示出足够的数据形式。不是输出来让人看的,主要是完成相应的条件控制等。输出此类数据一般用于调试,因此,如果输出这类数据,最好以16进制方式输出,为的是看清楚这个内存里存的是什么,而不是是多少。
说了许多,纯属个人见解,希望对你有帮助。
更多追问追答
追问
b1为1 0101 b2为10 和补码问题 这些我都知道 就是算出来的结果 和编译器出来的不一样。
我算的是aa.b1 = -21 aa.b2 = -2
追答
b1为1 0101 b2为10 都是补码
因为它们都是有符号数(int),所以第一位看作符号位,两个数都是负数
负数原码=(补码-1)的反码
10101 -1 = 10100 反码=1 1011 = -11
10 是负0 反码中的负0为负的最大值,即-2 这是规定
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询