函数接受两个参数,一个字节和一个位字段,并返回字节中字段的值

时间:2011-06-09 15:35:51

标签: c++ c bit-fields

我在网上发现了一些执行此任务的代码:

byte = byte >> field;
byte = byte & 0x01;
return(byte);

但是,我不明白为什么我们不能这样做:

return(byte & field);

这会有用吗?为什么或者为什么不?是否有更好的实施?

6 个答案:

答案 0 :(得分:3)

第一个相当于:

return (byte >> field) & 0x01;

它真正做的是转移到位置为field的位,如果该位置位则返回1,否则为0

您建议的那个是不正确的,因为它不会移动到指定字段的偏移量。例如,byte & 5没有任何意义。

该功能也可以这样写:

return byte & (1 << field);

当然,如果您打算将1 << 5传递给它而不是5,您可以按照自己的方式编写。

我认为field是一个数字,表示我们感兴趣的位的位置,因此对于单个字节,它将在0..7范围内。

答案 1 :(得分:1)

在第一个代码示例中,field是您想要该值的字段中位的位置。

在第二个样本中,字段必须是一个int,该位设置为1,即1 << field

答案 2 :(得分:1)

如果你真的希望返回值为零或者你可以

return ((byte & (1 << field)) != 0);

return ((byte >> field) & 0x01);

如果您关心的只是返回值为零或非零,则两种形式都会简化一些。

答案 3 :(得分:1)

将字节移到右边

field表示从右侧(LSB)获得的单词的位数。 byte = byte >> field会将字节field的位号byte置于LSB位置。然后byte = byte & 0x010x01的字节,这意味着如果最初在位号1中设置了位,则结果将在LSB中包含field,或者将包含如果在该位置清除了位,则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 & field来检查编号为field的位是否已设置或清除。这是因为field只是二进制而不是掩码。如果我们byte & field,则会发生以下情况。

  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

field的值为0x04,即其位数2已设置。通过此操作,我们实际检查了是否设置了位号2。如果field的值为5,则会设置位02,因此如果提取位{{1 {}}和0的值2,可以采用四种可能的组合。

向左移动0x01并进行掩码

测试byte的位值的其他方法不是移动byte本身,而是将byte掩码0x01向左移动,并且AND它与字节,并检查是否为零。 field编号位置位时(byte & (0x01 << field)) != 0为真,否则为假。

field

使用预先计算的掩码

如果你有一个需要定期测试的特定格式的字节,例如某些预先定义的字的某个位域,其中每个位意味着某些特定的东西,那么你可以保留预编译器掩码,它只有一个特定的将使用该掩码测试的位位置。例如,要检查一个字节,预计算机掩码将是:

   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.

为了测试#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) 中的第4位,我们必须bytereturn (byte & BIT_4)

根据位位置的含义,可以设置宏的名称。

答案 4 :(得分:0)

第一个示例将所需位移入返回的LSB,但第二个示例只是屏蔽掉所有不需要的位。

答案 5 :(得分:-1)

这可以通过结构给出。让我们说:

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) ;

}