首页 > 解决方案 > 有人可以向我解释这个按位函数中的 putchar 行吗?

问题描述

有人知道 1u 在此功能中的作用吗?下面的函数接受一个整数并打印出它的位。我想弄清楚的线是 putchar 线。我看到它需要一个无符号整数作为参数,并在循环中以二进制数的大小迭代一个或零,这恰好发生在 8*sizeof(int) 并对表达式 (1u << i) 其中 i 只是决定要转移多少位的循环的迭代。1u 中的 u 只是声明数字无符号数的修饰符吗?我试图准确了解此函数中的 putchar 行如何使用该行显示 x 的每一位。

它是一个 & 按位运算,所以如果 x 中的位和 (1u << i ) 的位都为 1,则循环 putchars 为 1,否则为 0。但由于我不太了解 1u 是什么,我真的不明白知道将位 i 向左移动是为了打印出 x 的位。

有人可以用外行的话对我说吗?

void showbits( unsigned int x )
{
    for (int i = (sizeof(int) * 8) - 1; i >= 0; i--)
    {
        putchar(x & (1u << i) ? '1' : '0');
    }
    printf("\n");
}

标签: cbit-manipulationputchar

解决方案


代码打印出二进制表示x

这条线

for (int i = (sizeof(int) * 8) - 1; i >= 0; i--)

makei的值从“number_of_bits_in_an_int” - 1 到 0。

因此,如果我们假设 int 的大小为 4(字符),则代码可以写成:

for (int i = 31; i >= 0; i--)

因此,在这种情况下,循环可以扩展为:

putchar(x & (1u << 31) ? '1' : '0');
putchar(x & (1u << 30) ? '1' : '0');
putchar(x & (1u << 29) ? '1' : '0');
...
putchar(x & (1u <<  1) ? '1' : '0');
putchar(x & (1u <<  0) ? '1' : '0');

然后(1u << ..)可以计算零件。1u是一个无符号整数,值为 1,左移了多次。它产生一个从 MSB 开始的步行 1 位模式。喜欢:

1000.0000.0000.0000.0000.0000.0000.0000  (i.e. 1u << 31)
0100.0000.0000.0000.0000.0000.0000.0000  (i.e. 1u << 30)
0010.0000.0000.0000.0000.0000.0000.0000  (i.e. 1u << 29)
...
0000.0000.0000.0000.0000.0000.0000.0010  (i.e. 1u << 1)
0000.0000.0000.0000.0000.0000.0000.0001  (i.e. 1u << 0)

当此模式是按位并x使用&并且结果用作布尔值时,它将在相应位x为 1 时生成真(如果为零则为假)。

所以代码可以写成这样的伪代码:

putchar(is_bit_31_in_x_set ? '1' : '0');
putchar(is_bit_30_in_x_set ? '1' : '0');
putchar(is_bit_29_in_x_set ? '1' : '0');
...
putchar(is_bit_1_in_x_set ? '1' : '0');
putchar(is_bit_0_in_x_set ? '1' : '0');

如果 int 的 sizeof 不是 4(如上所述),代码仍将打印二进制表示 - 只是使用其他位数。例如 sizeof int 为 2,循环将从 15 下降到 0。


推荐阅读