C++ 函数接受两个参数,一个字节和一个位字段,并返回字节中字段的值
我在网上找到了一些执行此任务的代码:C++ 函数接受两个参数,一个字节和一个位字段,并返回字节中字段的值,c++,c,bit-fields,C++,C,Bit Fields,我在网上找到了一些执行此任务的代码: byte = byte >> field; byte = byte & 0x01; return(byte); 然而,我不明白为什么我们不能这么做: return(byte & field); 这样行吗?为什么?有更好的实现吗?在第一个代码示例中,字段是您想要其值的位在字段中的位置 在第二个示例中,字段必须是一个int,该位设置为1,即1第一个字段相当于: return (byte >> field) &
byte = byte >> field;
byte = byte & 0x01;
return(byte);
然而,我不明白为什么我们不能这么做:
return(byte & field);
这样行吗?为什么?有更好的实现吗?在第一个代码示例中,字段是您想要其值的位在字段中的位置
在第二个示例中,字段必须是一个int,该位设置为1,即
1第一个字段相当于:
return (byte >> field) & 0x01;
它真正做的是移动到带有位置字段的位
并返回1
,如果该位已设置,则返回0
Operation: (0x01 << field)
Shifting 0x01 to the left field times field = 0x04 for the example
= 0x01 = 0 0 0 0 0 0 0 1
shift 1 = 0x02 = 0 0 0 0 0 0 1 0
shift 2 = 0x04 = 0 0 0 0 0 1 0 0
shift 3 = 0x08 = 0 0 0 0 1 0 0 0
shift 4 = 0x10 = 0 0 0 1 0 0 0 0
After the left shift the '1' moves in the bit position 4
Now we AND this with the byte to check if the bit position 4
is set or clear.
byte = 0x52 = 0 1 0 1 0 0 1 0
AND & & & & & & & &
(0x01 << field) = 0x10 = 0 0 0 1 0 0 0 0
---- ---------------
0x10 0 0 0 1 0 0 0 0
Therefore the answer (0x01 != 0) is 1 there fore the bit 4 is set. It the bit 4
was not set then the answer would be 0.
您建议的是不正确的,因为它不会移动到指定字段的偏移量。例如,byte&5
没有任何意义
函数也可以这样编写:
return byte & (1 << field);
返回字节&(1如果您确实希望返回值为零或一,您可以
return ((byte & (1 << field)) != 0);
如果您只关心返回值为零或非零,则这两种形式都会简化位。第一个示例将所需位移到返回的LSB中,但第二个示例只是屏蔽了所有不需要的位。将字节右移
字段
表示从右侧(LSB)输入的单词的位号.byte=byte>>字段
将把字节
byte
的位号字段
带到LSB位置。然后byte=byte&0x01
和带有0x01
的字节,这意味着如果最初在位号字段
中设置了位,结果将在LSB中包含一个1
,或者将包含一个在a0
上,如果在该位置清除了位
例如,检查字节0x52
是否设置了位号4
所需的测试如下所示
byte = 0x52 = 0 1 0 1 0 0 1 0
field = 0x04 = 0 0 0 0 0 1 0 0
Operation: byte = byte >> field
The bit number 4 is single quoted below. Note how it moves
intermediate byte | lost bits during
states | right shifting
byte = 0x52 = 0 1 0 '1' 0 0 1 0 |
shift 1 = 0x29 = 0 0 1 0 '1' 0 0 1 | 0
shift 2 = 0x14 = 0 0 0 1 0 '1' 0 0 | 1 0
shift 3 = 0x0A = 0 0 0 0 1 0 '1' 0 | 0 1 0
shift 4 = 0x05 = 0 0 0 0 0 1 0 '1' | 0 0 1 0
Note that the bit 4 is now moved at the LSB/righ most position of the byte
now if we test the rightmost position of the above byte then we can check
if the bit number 4 had its bit set or cleared, with the following operation
Operation: byte = byte & 0x01
byte is now 0x05
byte = 0x05 = 0 0 0 0 0 1 0 '1'
AND & & & & & & & &
0x01 = 0 0 0 0 0 0 0 1
---- ----------------
0x01 0 0 0 0 0 0 0 1
Now byte contains 0x01 so bit number 4 had the bit set. In the other case the
final answer would be 0.
但是我们不能用字节和字段来检查编号为字段的位是否被设置或清除。这是因为字段只是一个二进制文件,而不是掩码。如果我们用字节和字段来检查,则会发生以下情况
byte = 0x52 = 0 1 0 1 0 0 1 0
AND & & & & & & & &
field = 0x04 = 0 0 0 0 0 1 0 0
---- ---------------
0x00 0 0 0 0 0 0 0 0
字段
的值为0x04
,即设置了其位号2
。通过此操作,我们实际检查了位号2
是否已设置。如果字段
的值为5
则将设置位0
,以及2
,因此如果位0
和2
在byte
值中的状态牵引,可采取四种可能的组合
将0x01移到左侧并制作遮罩
测试字节
位值的其他方法不是移动字节
本身,而是将0x01
掩码字段
向左移动几次,然后将其与字节一起移动,并检查是否为零。(字节&(0x01这可以由结构给出。假设:
struct POWERTRAIN_ERROR
{
uint8 ERROR_CODE;
unit8 LAMP_STATUS : 1;
};
struct POWERTRAIN_ERROR pt_error;
uint8 func ( struct POWERTRAIN_ERROR pt)
{
// do something with pt.ERROR_CODE (which is a byte) and pt.LAMP_STATUS which is a bit field
// lets say, this function needs to return the status of 0th bit of ERROR_CODE
return ( pt.ERROR_CODE & 0x1) ;
}
如果你一个接一个地得到所有的位,那么应用于字段的序列是(0,1,2,3,4,5,6,7,8,9…)还是(0,1,2,4,8,16,32,64…)?你的第二个例子的工作方式并不完全相同-它不是返回0
或1
,而是返回0
或1
#define BIT_0 0x01 //(00000001)
#define BIT_1 0x02 //(00000010)
#define BIT_2 0x04 //(00000100)
#define BIT_3 0x08 //(00001000)
#define BIT_4 0x10 //(00010000)
#define BIT_5 0x20 //(00100000)
#define BIT_6 0x40 //(01000000)
#define BIT_7 0x80 //(10000000)
struct POWERTRAIN_ERROR
{
uint8 ERROR_CODE;
unit8 LAMP_STATUS : 1;
};
struct POWERTRAIN_ERROR pt_error;
uint8 func ( struct POWERTRAIN_ERROR pt)
{
// do something with pt.ERROR_CODE (which is a byte) and pt.LAMP_STATUS which is a bit field
// lets say, this function needs to return the status of 0th bit of ERROR_CODE
return ( pt.ERROR_CODE & 0x1) ;
}