C:对一小段代码的混淆 - 什么是'&0x'?

Mwi*_*s03 1 c variables hex

我是C的新手,我正试图在这个代码的和平中锻炼两件事;

  • &0xfe和&0x01的目的是什么?
  • __u16显然这是一个变量,但它们叫什么类型和什么?

提前致谢!

static __u16 smile_bmp[] = {0x3C, 0x42, 0x95, 0xA1, 0xA1, 0x95, 0x42, 0x3C};

displayImage(smile_bmp,res, daddress, file);

int displayImage(__u16 bmp[], int res, int daddress, int file)
{
    int i;
    for(i=0; i<8; i++)
        {
         block[i] = (bmp[i]&0xfe) >>1 | (bmp[i]&0x01) << 7;
        }
    res = i2c_smbus_write_i2c_block_data(file, daddress, 16,
        (__u8 *)block);
    sleep(1);
}
Run Code Online (Sandbox Code Playgroud)

Jer*_*fin 8

表达式:(bmp[i]&0xfe) >>1 | (bmp[i]&0x01) << 7作为一个整体实际上是8个最低有效位的旋转(也称为循环移位)bmp[i].

bmp[i] & 0xfe部分将数字输入bmp[i]并屏蔽掉低位(0xfe意思是"十六进制的FE",转换为11111110二进制),所以当你们and两个在一起时,它将最低位设置为0而不改变任何其他位(井) ,8个最低有效值中的任何一个 - 给定bmp[i]类型__u16,它显然有16位,因此掩码中的高8位也是零,因此它们也在结果中设置为零).

同样地,该bmp[i] & 0x01部件除了最低位之外的所有屏蔽.0x01为00000001,因此当您and使用其他任何值时,保留最低有效位的原始值,并将所有其他位设置为0.

然后将第一个向右移动一位,将第二个向左移动7位,然后使用按位or将两个部分重新组合在一起.最终结果是从位0开始的位现在是位7,并且所有其他位移到右侧的位置(前一位7现在位6,前一位6现在位5,等等)

顺便说一下,名称__u8__u16保留用于实现,因此除非实际提供这些名称,否则您有未定义的行为(即,您不允许在代码中定义这些名称).

  • @ Mwilliams03:显而易见的原因是,如果你想确保类型总是正好是16位,那么`int`可以是从16开始的任何东西.执行此操作的标准方法是`#include <stdint.h>`并使用`uint16_t`作为类型. (2认同)

sim*_*onc 5

它是左侧变量()的按位 AND bmp[i]和表示为十六进制的常量