#include <stdio.h>
int main()
{
char str[17];
getBin(3334, str);
printf("%s\n", str);
return 0;
}
void getBin(int num, char *str)
{
*(str+16) = '\0';
int mask = 0x8000 << 1;
while(mask >>= 1)
*str++ = !!(mask & num) + '0';
}
我真的不明白while循环是如何运作的。有人可以用简单的语言解释它在做什么吗?感谢
答案 0 :(得分:4)
是的,当然。所以0x8000
= 8 * 16 ^ 3 = 2 ^ 15。现在,如果再向左移动一次,则得到2 ^ 16。
while循环不断地掩盖所有值:
因此while循环将mask视为常规整数中2的幂的迭代器。
现在!!(mask & num)
做了什么?如果掩码指示的位被翻转on
,则返回1;如果是off
,则返回0。
表达式!!(mask & num)
返回0或1并添加到0
的字符代码中,它返回0
或1
的字符代码。
例如,如果num=12
和mask=4
,那么!!(4 & 12) = !!(100 & 1100) = !!(100)= !0 = 1
。现在,如果你添加1 + '0'
你会得到什么?您得到1+48=49
,这是1
的字符代码。
*str++ = ..
将值赋给字符串中的特定位置,然后将指针递增以指向下一个字符。
问题是:str
是否以null结尾?
我认为行*(str+16) = '\0';
负责空终止,因为它会预防性地设置空终止字节。
所以我想这是对你上面写的代码的解释。
答案 1 :(得分:1)
void getBin(int num, char *str)
getBin()
需要一个数字(num
)和一个字符串来写入(str
)
*(str+16) = '\0';
str
的最后一个字符设置为NULL终止符
int mask = 0x8000 << 1;
我们创建一个名为mask
的变量,并将其设置为0x8000左移1,即0x10000。为什么?可能更容易在二进制文件中看到:
0x8000 16 =&gt; 1000 0000 0000 0000 2 (然后将所有东西都移到1处)
1 0000 0000 0000 0000 2 =&gt; 0x10000的<子> 16 子>
while(mask >>= 1)
当mask
大于0时,我们向右移1位,并将结果保存回mask
。 (>>=
表示向右移动并保存)。这意味着价值将是:
0x10000 16 == 1 000 0000 0000 0000 2 == 65536 10
0x8000 16 == 1000 0000 0000 0000 2 == 32768 10
0x4000 16 == 100 0000 0000 0000 2 == 16384 10
0x2000 16 == 10 0000 0000 0000 2 == 8192 10
...
0x4 16 == 100 2 == 4 10
0x2 16 == 10 2 == 2 10
0x1 16 == 1 2 == 1 10
最后在每个迭代中:
*str++ = !!(mask & num) + '0';
此代码取num
中的每个数字,并将其与mask
中设置的1位进行对比,然后检查结果是否为== 0
,然后添加字符0
的值,并将最后的ASCII“数字”存储到字符串中,然后递增字符串。
让我们一步一步地打破这一步:
mask & num // num is 3334 = 0011 0011 0011 0100
// mask starts at = 1000 0000 0000 0000
因此,在第一次迭代中,(mask & num)
的值为0
。
!!(x)
与说(x == 0 ? 0 : 1)
相同所以在第一次迭代中我们有0
所以!!(0)
给我们0,我们想将它存储到我们的字符串中,但我们希望它是一个ascii角色。 0的ASCII字符是0x30 16 所以我们将0x30加到0并得到0x30(或'0'
)然后
*str++ = '0';
我们取消引用str
并存储字符0,然后我们有一个后增量移动到字符串中的下一个字符。