c - 有人可以向我解释这个按位函数中的 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");
}
解决方案
代码打印出二进制表示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。
推荐阅读
- python - Paramiko:打开后台进程
- python - 如何创建随机浮点数并将它们添加为熊猫中的数据框列?
- django - 如何自动将用户模型组合到自定义用户模型
- reactjs - 托管在 S3 上的静态 GatsbyJS 站点中的动态 Open Graph 元标记
- go - 通过引用分配
- python - “if”语句在 twilio 短信项目中表现得很奇怪
- c - 通过指针传递总和,产生输出错误
- excel - Excel vba用户自定义函数过滤多维数组;比循环更有效的选择?
- scala - Spark:如何告诉 Spark 使用本地 hadoop 而不是其嵌入式 hadoop?
- python - 如何使用 interp1d 为时间序列数据绘制平滑曲线?