2013-03-13 283 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