2013-03-13 109 views
2
#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位二进制转换代码

回答

4

是的,当然。所以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它返回的字符码为01字符代码。

因此,例如,如果num=12mask=4然后!!(4 & 12) = !!(100 & 1100) = !!(100)= !0 = 1。现在,如果你添加1 + '0'你会得到什么?你得到1+48=49这是1的字符编码。

*str++ = ..将值赋给字符串中的特定位置,然后递增指针指向下一个字符。

现在的问题是:str是否为空终止?

我认为行*(str+16) = '\0';照顾空终止,因为它预防性地设置空终止字节。

所以我想这是对你上面写的那段代码的解释。

+2

另请注意,代码将在8位或16位计算机上崩溃并刻录,其中int为16位。 – Lundin 2013-03-13 07:49:53

+0

很高兴知道。如果像MSP430这样的16位微处理器运行,任何人都有更好的方法? – cii 2013-03-13 17:49:01

1
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,那么我们有后增量移动到下一个字符串中的字符。

+0

谢谢。这也是一个很好的答案 – cii 2013-03-13 18:05:48