1

我是 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);
}
4

2 回答 2

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]is 类型__u16,它显然有 16 位,因此掩码中的高 8 位也是零,因此它们在结果中也设置为零)。

同样,该bmp[i] & 0x01部分屏蔽了除最低位之外的所有内容。0x01 是 00000001,所以当你and将此值与其他任何值一起使用时,保留最低有效位的原始值,并将所有其他位设置为 0。

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

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

于 2013-01-11T15:58:49.570 回答
5

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

于 2013-01-11T15:50:40.653 回答