日期:2015年1月13日 10:40 星期二 农历 甲午 马年 十一月廿三
正文:
在产品代码中经常用位段(位域)表示某个flag,在本次编程竞赛的编解码部分也反复用到了位段操作,因此本次把位段总结一下,以便后续学习。前面6条是从谭浩强同志的书上抄下来的,后面的几条是我自己总结的。
(1)一个位段必须存储在同一个存储单元中,不能跨两个单元。(这里所说的存储单元就是说位段前面的那个类型所表示的长度)
(2)位段的长度不能大于存储单元的长度(废话,已经包括在第一点中了),不能定义位段数组。
(3)可以定义匿名位段,只需要在定义的还是把变量名省略即可,表示那个空间不用。
(4)如果想要下一个位段字段从新的存储单元开始,只需要在这个位段字段的前面定义一个长度为0的匿名位段即可。
(5)位段字段可以用整形格式符输出。
(6)位段可以在数值表达式中引用,它会被系统自动转换为整形数。
(7)位段字段是不能进行取地址操作的,否则编译器会报错。
(8)位段与整形数一样,也有大小字节序之分,大小字节序的特征与同机器的整形数一致。
(9)对于位段字段在小终端上的表现类似与整形数有相同的地方也有不同的地方。相同的地方就是从右向左垒砖头,例如WORD32 a = 0x12345678;
就是从右到左按字节垒砖头,最终的结果为: 0x78 0x 56 0x34 0x12,换成位段的话,也是一致的。不同的地方是开始的位置不一样了,前面的WORD32的例子是从第4个字节开始往前垒,但是位段不一样,它是从第一个字节的末尾bit开始往前垒,整个位段字段作为一个整体来垒,位段内部的比特不再区分大小字节序。举例(假如该结构体对象初始化为全0):
typedef struct
{
WORD32 btB1 :4;
WORD32 :2;
WORD32 btB2 :3;
}T_TestBits;
如果btB1 = 6; 那么这个结构体的第一个字节就是0x06
但是如果要跨字节了,整个位段字段整体就必须拆分了,例如说btB2字段,它跨两个字节,那怎么办呢?编译器会自动把它的超出的高比特放到第二个字节的最右边去。就是说,如果btB2=1,那么第一个字节为0x40,第二个字节为0x00,如果btB2=3,那么第一个字节为0xC0,第二个字节为0x00,如果btB2=6,那么第一个字节为0x80,第二个字节为0x01
(10) 疑问:如果在大终端机器上,如果位段字段跨字节,会把位段字段的高比特还是低比特放到第二个字节中去呢?我猜答案应该与小终端相反,应该是低比特。
正文:
在产品代码中经常用位段(位域)表示某个flag,在本次编程竞赛的编解码部分也反复用到了位段操作,因此本次把位段总结一下,以便后续学习。前面6条是从谭浩强同志的书上抄下来的,后面的几条是我自己总结的。
(1)一个位段必须存储在同一个存储单元中,不能跨两个单元。(这里所说的存储单元就是说位段前面的那个类型所表示的长度)
(2)位段的长度不能大于存储单元的长度(废话,已经包括在第一点中了),不能定义位段数组。
(3)可以定义匿名位段,只需要在定义的还是把变量名省略即可,表示那个空间不用。
(4)如果想要下一个位段字段从新的存储单元开始,只需要在这个位段字段的前面定义一个长度为0的匿名位段即可。
(5)位段字段可以用整形格式符输出。
(6)位段可以在数值表达式中引用,它会被系统自动转换为整形数。
(7)位段字段是不能进行取地址操作的,否则编译器会报错。
(8)位段与整形数一样,也有大小字节序之分,大小字节序的特征与同机器的整形数一致。
(9)对于位段字段在小终端上的表现类似与整形数有相同的地方也有不同的地方。相同的地方就是从右向左垒砖头,例如WORD32 a = 0x12345678;
就是从右到左按字节垒砖头,最终的结果为: 0x78 0x 56 0x34 0x12,换成位段的话,也是一致的。不同的地方是开始的位置不一样了,前面的WORD32的例子是从第4个字节开始往前垒,但是位段不一样,它是从第一个字节的末尾bit开始往前垒,整个位段字段作为一个整体来垒,位段内部的比特不再区分大小字节序。举例(假如该结构体对象初始化为全0):
typedef struct
{
WORD32 btB1 :4;
WORD32 :2;
WORD32 btB2 :3;
}T_TestBits;
如果btB1 = 6; 那么这个结构体的第一个字节就是0x06
但是如果要跨字节了,整个位段字段整体就必须拆分了,例如说btB2字段,它跨两个字节,那怎么办呢?编译器会自动把它的超出的高比特放到第二个字节的最右边去。就是说,如果btB2=1,那么第一个字节为0x40,第二个字节为0x00,如果btB2=3,那么第一个字节为0xC0,第二个字节为0x00,如果btB2=6,那么第一个字节为0x80,第二个字节为0x01
(10) 疑问:如果在大终端机器上,如果位段字段跨字节,会把位段字段的高比特还是低比特放到第二个字节中去呢?我猜答案应该与小终端相反,应该是低比特。