Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 函数接受两个参数,一个字节和一个位字段,并返回字节中字段的值_C++_C_Bit Fields - Fatal编程技术网

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
,或者将包含一个
在a
0
上,如果在该位置清除了位

例如,检查字节
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) ;

}