为何右移unsigned char后需与1做按位与才能得到正确二进制值?
关于
print_bits函数中& 1操作的疑问 问题背景
我正在完成一个名为print_bits的编程练习,要求实现一个函数接收一个字节,以二进制形式打印且末尾无换行,函数声明为void print_bits(unsigned char octet);,示例传入2时输出"00000010"。
参考解决方案代码如下:
#include <unistd.h> void print_bits(unsigned char octet) { int i; unsigned char bits; i = 8; while (i--) { bits = (octet >> i & 1) + '0'; write(1, &bits, 1); } }
我理解大部分逻辑,但有个疑惑:对unsigned char右移后,为什么要和1执行按位与操作?我原以为直接右移就能得到0或1,但去掉这个操作后运行程序,结果远不是0和1,想知道原因。
原因解析
核心问题在于右移操作不会自动清除高位的冗余数据。
举个实际例子:假设octet的值是0b10101010(十进制170),当执行octet >> 3时,得到的是0b00010101(十进制21)——这个结果里除了我们需要的最低位,高位还保留着原数据的其他位信息,并不是单纯的0或1。
而& 1这个按位与操作的作用,就是只保留结果的最低位,把所有高位强制清零:
- 按位与1时,只有最低位会和1进行运算:如果最低位是1,结果就是1;如果是0,结果就是0。
- 不管右移后的数值高位是什么,经过
& 1后都会变成0,最终得到的就只有0或1这两个我们需要的结果。
如果去掉& 1,直接把右移后的数值加上'0',相当于把一个大于1的整数转成字符,得到的就不是'0'或'1'了,而是ASCII表中对应的其他字符,所以运行结果会完全不符合预期。
内容的提问来源于stack exchange,提问作者Joao Pereira
相关产品推荐
相关产品推荐

