標籤:
本篇介紹C/C++語言中的進位的概念,主要介紹2進位、10進位、16進位,這三種是編程時必須掌握的也是最經常使用的。另外,介紹8進位和36進位,當中 36進位在實際project項目中會遇到。 (本文選自《C/C++學習指南》。邵發。附錄“2進位,10進位,16進位”)講2進位、10進位、16進位的視頻教程,點擊觀看
權利聲明:作者擁有本書的所有權利。
作者授權不論什麼人都能夠自由轉載本網站公布的內容,但轉載時必須遵守下面限制: ①轉載時必須全文轉載。不得有不論什麼改動,必須包括“權利聲明”和“官網地址” ② 僅限於網路轉載,即終於結果發佈於網路上。凡是不遵守以上兩條的轉載行為視為侵權行為。
除非本人同意。不論什麼人不得將本網站內容內容用於不論什麼的其它用途。
官網地址: http://www.afanihao.cn/ 留言請到http://www.afanihao.cn/kbase/
1.1 引例一
先給出一段代碼,請讀者如今馬上編譯執行一遍。觀察結果。
#include <stdio.h>void main(){ int a = 'A'; int b = 65; int c = 0x41; printf("%d, %d, %d \n", a, b, c);}
假設你還沒有動手編譯,那麼請馬上終止閱讀本書,由於本書不是為太懶的人準備的。全部代碼和示範範例,請讀者務必自己手打一遍,不要拷貝。假設你是拷貝過去的,請馬上燒掉本書。謝謝。
你會發現,輸出結果為:
是的,變數a,b,c的值全然同樣。實際上,這三種初始化(賦值)方法是全然等價的,僅僅是寫法不一樣而已。
你用哪一種辦法都能夠。
1.2 引例二
再給出還有一段代碼,請馬上編譯和執行一下:
#include <stdio.h>void main(){ char a = 65; printf("%d, %02X , %c \n", a, a, a);}
它的執行結果為:
是的,對於同一個整數a。當它作為十進位顯示時。顯示為65;當作為十六進位顯示為,顯示為41,當作為字元顯示時,顯示A。
1.3 引例三
假設上面的範例給你的印象還不夠深刻。再嘗試一個範例:
#include <stdio.h>void main(){ // 下面變數a和b的值是同樣的 int a = 0x12345678; int b = 305419896; printf("%d, %d \n", a, b); // buf的內容為"ABC" char buf[4] = { 0x41, 66, 'C' , 0}; printf("%s \n", buf);}
結果為:
1.4 整型變數的2進位表示
本節內容對理解本章乃至全書都極為重要。假設你理解了,那麼所謂進位問題對你就不再是個問題。
首先,在第三章中已經明白的強調。每一個變數都是具有一個記憶體位址的。對於char型變數來說。在記憶體中佔了1個位元組。對於int型變數來說,在記憶體中佔了4個位元組。
為了讓你更easy的理解,我們就先從char開始吧。
然後,我們看一下在電腦的記憶體裡。倒底是怎麼儲存的。我們從最最簡單的數開始。比如。定義一個變數 char a = 13,此變數a佔了一個位元組的記憶體。
在記憶體中,一個位元組有8個位(bit),每個位能夠是1或0。
那麼a的表示為:
就是說,在實體記憶體中,它就是這麼儲存的。
至於物理上怎樣表示1,怎樣表示0,讀者是不須要關心的。
你能夠簡單地覺得一個位就相應一個“開關”。1表示開啟,0表示關閉。以後,我們就稱它的按位表示為 0000 1101 。
所以,char a = 13 或者char a = 0x0C ,這兩種寫法表示的意思是一樣的:分配一個變數,相應一個位元組。位元組的按位物理表示為 0000 1101。
明確了嗎?所謂10進位還是16進位是對人類而言的。不是同的說法。
可是對於電腦而言,要儲存這個數值。就是要用8個位(相應8個物理開關)。
這是哲學上的“形式和內容”的關係。
反過來,已經知道一個變數a的記憶體表示為 0000 1101,我們想在控制台上把它的值顯示出來。
那麼能夠按10進位顯示。也能夠按16進位顯示。
對你是小學生水平,那好吧,作為程式猿我僅僅好給按10進位顯示給你了。
printf (" %d ", a);
假設你有碰巧看過本書,那好吧。我給按16進位顯示:
printf(" %02X ", a);
1.5 進位換算
這一節介紹的是數學裡的內容。
作者的數學水平不高,在這裡僅僅能讓你大概地理解一下。
實際上,正如作者一再強調的。編程不須要太高的數學水平,差點兒對數學是沒有要求的。
首先。說說從16進位到10進位的換算。我們知道,0x41(十六進位) 和65(十進位)是等價的。那麼怎麼手工計算呢?以下給出示範範例:(以下不是代碼,是在草稿紙的手算方法)
0x41 = 4 * 16 + 1 = 65
0x12345678 = 1 * 167 + 2 * 166 + 3*165 + 4 * 164 + 5 * 163 + 6 * 162 + 7 *161 + 8 = 305419896
能夠看出。對於16進位,每個數字上的權重就是 16n-1 (即16的n-1次方)
然後,說說從2進位到10進位的換算。
0000 1101 = 0 + 0 + 0 + 0 + 8 + 4 + 0 + 1 = 13
或者嚴格一點:
0000 1101 = 0 + 0 + 0 + 0 + 23 + 22+ 0 + 1 = 13
能夠看出,對於2進位,每個數字上的權重就是2n-1(即2的n-1次方)
1.6 怎樣列印2進位
在printf參數中,使用控制符%d能夠按10進位列印。使用%X能夠按16進位列印。那麼,有沒有按2進位列印呢?
非常遺憾,printf不能直接列印二進位。
為了彌補這個遺憾,作者貢獻一個按2進位列印的函數。
#include <stdio.h> // 把一個整數轉成二進位字串// value: 輸入整數// buf: 輸出字串// num_of_bits: 指定要列印的位元void to_binary(unsigned int value, char buf[], int num_of_bits){ for(int i=0; i<num_of_bits; i++) { unsigned int mask = 1 << (num_of_bits -1 - i); if ( value & mask) buf[i] = '1'; else buf[i] = '0'; } buf[num_of_bits] = 0;} void main(){ char buf[33]; to_binary(135, buf, 8); printf("%s \n", buf);}
1.7 8進位
8進位在project實際中一般不會用到。這個使用方法沒有價值。和前面的類似。8進位表示每一個數位權重是8n-1(即8的n-1次方)。比如,15(八進位)等於13(十進位)。
在C/C++語言中,八進位的字面常量以0開頭。
比如以下的代碼。
#include <stdio.h>void main(){ int a = 015; // 以0開頭表示八進位 int b = 0x0D; // 以0x開頭表示十六進位 int c = 13; // 十進位 printf("%d, %d, %d \n", a, b, c);}
1.8 36進位
正如序列 0, 1, 2, ..., 9, A, ..., F來表示16進位一樣,用序列0, 1, 2, ...,9, A, B, ..., Y, Z來表示36進位。其運算方法也全然是一樣的,每個數位權重是36n-1(36的n-1次方)。
比如。(下面不是代碼。是草稿紙上的手算方法)
2Z = 36 * 2 + 35 = 107
其實,36進位在project實踐中是一個非常實用的知識。比方。相同用4個字元來表示數字。使用10進位能夠表示0000~9999,使用16進位能夠表示0000~FFFF,使用36進位能夠表示0000~ZZZZ。
能夠,使用36進位的表示能力最強。
詳解2進位,10進位,16進位,8進位,36進位