到目前为止,我们学习的C语言程序,都是以字节为单位,譬如64位操作系统下,int类型一般为4字节,long类型一般为8字节。
这样的程序编写久了,我们都好像把字节当成计算机的原子单位了。
其实呢,一个字节包含8个比特位,我们是可以把一个字节掰成几部分,每个部分使用一个或几个比特的。
看下面的例子:
#include #pragma pack(1)struct TSingleBits{ unsigned m_uiGrade:3; unsigned m_uiAge:5;};int main(){ struct TSingleBits singleBits; singleBits.m_uiGrade = 4; singleBits.m_uiAge = 10; printf('size of singleBits is : %lu', sizeof(singleBits)); printf('grade: %u', singleBits.m_uiGrade); printf('age: %u', singleBits.m_uiAge); return 0;}
解释一下,程序中使用了# pragma pack(1)编译选项,用于告诉编译器,这个程序使用的内存,逐个字节进行对齐。
程序的运行结果:
size of singleBits is : 1grade: 4age: 10
解释一下:
1、singleBits变量只占用1字节;
2、它的这1字节,又分成了两个部分m_uiGrade和m_uiAge;
3、m_uiGrade占用3比特;
4、m_uiAge占用5比特。
5、m_uiGrade和m_uiAge都是无符号类型的数据。
上面的例子,位域为无符号型。
我们把上面的例子修改一下:
#include #pragma pack(1)struct TSingleBits{ signed m_iGrade:3; signed m_iAge:5;};int main(){ struct TSingleBits singleBits; singleBits.m_iGrade = 3; singleBits.m_iAge = 10; printf('size of singleBits is : %lu', sizeof(singleBits)); printf('grade: %d', singleBits.m_iGrade); printf('age: %d', singleBits.m_iAge); return 0;}
程序的运行结果为:
size of singleBits is : 1grade: 3age: 10
代码如下:
#include #pragma pack(1)struct TSingleBits{ signed m_iGrade:1; signed m_iAge:5;};int main(){ struct TSingleBits singleBits; singleBits.m_iGrade = 1; singleBits.m_iAge = 10; printf('size of singleBits is : %lu', sizeof(singleBits)); printf('grade: %d', singleBits.m_iGrade); printf('age: %d', singleBits.m_iAge); return 0;}
程序编译后运行的结果是:
size of singleBits is : 1grade: -1age: 10
这里有一个比较奇怪的事情,我们明明给m_iGrade赋值为1,为什么结果为-1呢?
答案是,m_iGrade的取值范围为 -1~0,赋值为1越界了!
联系客服