最近工作中遇到了C/C++语言中的位结构,但是觉得有些微妙,所以就查阅了一些资料。
首先简介一下位结构的定义以及用法。
位结构是一种特殊的结构, 在需按位访问一个字节或字的多个位时, 位结构比按位运算符更加方便。
位结构定义的一般形式为:
struct位结构名{
数据类型 变量名: 整型常数;
数据类型 变量名: 整型常数;
} 位结构变量;
其中:
数据类型必须是int(unsigned或signed)。 整型常数必须是非负的整数, 范围是0~32, 表示二进制位的个数, 即表示有多少位。
变量名是选择项, 可以不命名, 这样规定是为了排列需要。
typedef struct
{
int m_a : 8;//占低字节的0-7 共8位
int m_b : 3;//占第二个字节的低三位
}BitStruct, *pBitStruct;
位结构成员的访问与结构成员的访问相同。可以通过BitStruct bitStruct.m_a来访问。
位结构的注意事项
1. 位结构中的成员可以定义为unsigned, 也可定义为signed, 但当成员长度为1时, 会被认为是unsigned类型。因为单个位不可能具有符号。
2. 位结构中的成员不能使用数组和指针, 但位结构变量可以是数组和指针,如果是指针, 其成员访问方式同结构指针。
3. 位结构总长度(位数), 是各个位成员定义的位数之和, 可以超过两个字节。
4. 位结构成员可以与其它结构成员一起使用。
代码定义如下:
typedef int BOOL;
#define TRUE 1
#define FALSE 0
typedef struct
{
BOOL m_a : 1;
BOOL m_b : 1;
}BitStruct, *pBitStruct;
在main函数中的实现:
BitStruct bitStruct;
bitStruct.m_a = TRUE;
bitStruct.m_b = FALSE;
if(bitStruct.m_a !=TRUE)
{
printf("It's TRUE! bitStruct.m_a = %d,bitStruct.m_b = %d/n",bitStruct.m_a,bitStruct.m_b);
}
else
{
printf("It's FALSE! bitStruct.m_a = %x,bitStruct.m_b =%d/n",bitStruct.m_a,bitStruct.m_b);
}
此时编译运行,就会打印出“It's FALSE! bitStruct.m_a = -1,bitStruct.m_b = 0”“-1其实就是0xFFFFFFFF”
代码里已经给m_a这个成员赋值为TRUE,但是通过比较发现问题,为什么打印FALSE呢?想了想觉得可能是编译器在处理的时候进行了补位,“0”全部补0,还是0,但是“1”却全部补1了。不知道是不是编译器的bug?
如果位结构占位不是1的时候,就不会有这种问题。