4位十进制到16位二进制转换代码
#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循环的功能。有人能够简单地解释它在做什么吗?谢谢4位十进制到16位二进制转换代码
是的,当然。所以0x8000
= 8 * 16^3 = 2^15。现在如果你再把它移到左边,你会得到2^16。
while循环汽车无通过所有的值取面膜:
- 2^15
- 2^14
- 2^13 ...
所以while循环将掩码视为一个普通整数中两个幂的迭代器。
!!(mask & num)
现在做什么?如果掩码指示的位被翻转,则它返回1 on
或0如果它是off
。
表达!!(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
是否为空终止?
我认为行*(str+16) = '\0';
照顾空终止,因为它预防性地设置空终止字节。
所以我想这是对你上面写的那段代码的解释。
void getBin(int num, char *str)
getBin()
接受一些(num
)和一个字符串写入(str
)
*(str+16) = '\0';
的str
的最后一个字符设置为NULL终止
int mask = 0x8000 << 1;
我们创造一个名为mask
的变量并将其设置为0x8000,左移1,即0x10000。为什么?可能更容易在二进制看到:
为0x8000 => 1000 0000 0000 0000 (然后移动一切左1米的地方) => 0x10000的
while(mask >>= 1)
虽然mask
大于0,我们右移1位,并返回结果保存到mask
。 (>>=
表示右移并保存)。这意味着这些值将是:
0x10000的 == 1 000 0000 0000 0000 == 65536
为0x8000 == 1000 0000 0000 0000 = = 32768
0x4000的 == 100 0000 0000 0000 == 16384
为0x2000 == 10 0000 0000 0000 == 8192
...
为0x4 == 100 == 4
0X2 == 10 == 2
0x1 == 1 == 1
最后在每个这些迭代:
*str++ = !!(mask & num) + '0';
此代码正在每个数字在num
,与1 AND'ing的它在mask
中设置,并检查结果是否为== 0
,然后它将字符0
的值加上并将最后的ASCII“number”存储到字符串中,然后递增该字符串。
让我们打破下来一步步时间:
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 所以我们添加的0x30为0,得到的0x30(或'0'
)然后
*str++ = '0';
我们提领str
并存储字符0,那么我们有后增量移动到下一个字符串中的字符。
谢谢。这也是一个很好的答案 – cii 2013-03-13 18:05:48
另请注意,代码将在8位或16位计算机上崩溃并刻录,其中int为16位。 – Lundin 2013-03-13 07:49:53
很高兴知道。如果像MSP430这样的16位微处理器运行,任何人都有更好的方法? – cii 2013-03-13 17:49:01