天天看點

《C語言程式設計:問題與求解方法》——1.1節二進制簡介

本節書摘來自華章社群《c語言程式設計:問題與求解方法》一書中的第1章,第1.1節二進制簡介,作者:何 勤,更多章節内容可以通路雲栖社群“華章社群”公衆号檢視

1.1 二進制簡介

為了從整體上把握計算機的基本工作原理,并為後面的程式設計學習奠定紮實的基礎,讀者有必要先對數字信号、二進制及其相關知識有比較清晰的、整體的了解。

1.1.1 二進制與二進制數的基本概念

二進制就是隻能用數字“0”和“1”來進行計數的數字系統。二進制加法運算的重要規則是: 1+1=10 ,即兩個1相加,就産生了向高位的進位,即“逢二進一”(做減法時則是“借一當二”),類似于十進制中的“逢十進一”(做減法時則是“借一當十”)。其他二進制加法規則更簡單:0+0=0、0+1=1、1+0=1。二進制與十進制、十六進制的對照如表1-1所示。

《C語言程式設計:問題與求解方法》——1.1節二進制簡介

延伸與拓展:二進制的算術運算規則非常簡單。這種簡單性是計算機采用二進制的一個重要原因。如何用邏輯門電路(在當代,主要是用大規模內建在矽晶片上的半導體邏輯門電路)來構成計算機中的二進制算術運算和邏輯運算電路這部分内容并不難懂,感興趣的讀者請參閱本書末尾列出的參考文獻。

與十進制數類似,在一個二進制數中,靠左邊的數字是高位數,靠右邊的數字是低位數。其中最左邊的位稱為最高位。

我們經常用一對圓括号包覆一個數值,并在圓括号外面加一個整數下标,用此下标來表示一個數值是幾進制數(但是對于十進制數,常常省略圓括号和下标)。比如,(1011)16是一個十六進制數,而(1011)2是一個二進制數。

二進制數的多項式展開表示

對于一個十進制整數,比如3785,其數值可用以下的多項式展開來表示:

我們把(1)式中10的幾次方稱為權重,權重左邊的乘數稱為系數。(1)式中共有4個系數,從左到右依次是“3”、“7”、“8”、“5”,權重依次分别是103、102、101、100。

可見,用這種記數法表示數值資料時,越左邊的系數所對應的權重越大。權重中的基數(即底)與表示該數的進制是一樣大的,在這裡都是10。

類似的,任意一個二進制整數,其數值也可用多項展開式來表示。比如,二進制整數1011可表示為

(2)式中系數從左到右依次是“1”、“0”、“1”、“1”,而權重依次分别是23、22、21、20。

展開式中系數的最大值一定比進制數小1。比如,在十進制計數系統中,系數的最大值是9,而在二計制計數系統中,系數的最大值是1。

下面我們先來熟悉一些與書寫、存儲或傳輸一串二進制數有關的術語。

1.1.2 與二進制數相關的術語:位、位串、位元組

1.位

書寫、存儲或傳輸單個的二進制數字稱為位(bit)。單個“位”中的數字不是0就是1,不可能有其他數字。

任何一個隻能處在兩個不同穩定狀态的電子元件(電容、觸發器等)或者某種(比如均勻覆寫着磁性顆粒的)媒體表面上的一個小點,都可以用來(間接)表示和存儲一個“位”。

2.位串及其長度

多個二進制數順序排列在一起稱為位串(有些教科書将其稱為“位模式”)。位串中含有的數字總個數稱為位串的長度。比如,位串100110的長度是6。處于位串左邊的位稱為高位,位于位串右邊的位是低位,位于位串最左邊的位稱為最高位。

3.度量位串長度的基本機關—位元組

“位”這個二進制的度量機關太小,用起來很不友善。現代的大多數計算機和一些數字處理裝置通常是以長度為8的位串—位元組(byte)來作為度量(部件或裝置的)資料存儲容量大小的一種基本機關。

把長度為8的一個位串稱為一個位元組,長度為16的一個位串稱為2個位元組。長度為n的位串一共有n/8個位元組。也就是說,一個位串的長度,既可以用位串中的總位數來度量,也可以用位串所具有的位元組數來度量。

延伸與拓展:二進制資料存儲和傳輸的其他一些常用機關

“位元組”這個基本機關的大小是“位”這個最小二進制機關的8倍,但是在很多場合仍然還是顯得太小,更大的常用機關有(在各種資料中,經常用字元b來表示位元組byte,用k來表示數值1024):

千位元組: 1kb=1024b=210b

兆位元組: 1mb=1024kb=210kb=220b=1048576 b(約為一百萬位元組)

千兆位元組: 1gb = 1024mb=210mb=230b=1073742814 b(約為十億七千多萬位元組)

注意:相鄰機關之間都是1024倍的關系,而不是1000倍的關系。

我們常常會看到一些資料儲存設備在辨別其資料存儲容量時使用kb(千位元組)、mb(兆位元組)或gb(千兆位元組)。

不過,在網絡和通信領域,人們還是習慣用“位”作為資料傳輸的基本機關。是以,通常所謂的10兆寬帶網,并不是每秒能夠傳輸10mb(10485760位元組)的資料,而是每秒傳輸10×106位(bit)。也就是說,在網絡通信領域,“兆”這個名詞就是精确地等于一百萬(即106)。

4.位串的通常傳輸方式—并行或串行

一個長度為n的位串,既可以用n根并排的導線同時進行傳輸,每根導線傳輸一個位,即并行傳輸(這種方式的傳輸速度很快,但要用多根導線);也可以用一根導線,分為n個相等時間段,一位一位地依次先後進行傳輸,即串行傳輸(這種方式的傳輸速度較慢,但隻要用一根導線)。

1.1.3 數和碼的含義與差別

如果計算機隻能夠對一些數值進行運算—在計算機剛發明的早期年代,确實就是如此—那麼它的應用範圍就必然很窄。現代計算機的應用範圍幾乎深入人類社會生産生活的方方面面。其根本原因在于:現代計算機不僅能夠對“數值”進行運算,還能夠借助于各種軟體和硬體,對間接表示世界上各種各樣事物的“碼”進行不同的處理。也就是說,同樣的一個位串,既可以用來表示數值,也可以用來表示各種不同僚物的“碼”。

是以,我們想要真正懂得計算機并且學好程式設計,就不僅要熟悉二進制的“數”,還必須對一些常見的二進制的“碼”有清晰的了解。

1.十進制的數和碼

我們先來通過一個例子,說明十進制數字系統中數與碼的差別。

如果3785用于表示數,則越高位(即越左邊的位)的數字越重要(因為權重越大)。而3785用來表示非數值的碼,則每一位數字都同樣重要。碼值僅相差一,所表示的文字(或代表的意義)就可以有巨大的差別(比如,3785可代表漢字“大”,而3786可代表漢字“小”)。

雖然十進制3785隻能直接表示唯一的一個非負整數,這個數的值是三千七百八十五;但是,同樣一個十進制的數字串“3785”,通過某種編碼,可以表示的事物種類卻是無限制的:碼3785既可以表示一個漢字,也可以表示任何碼值為3785的事物。

2.二進制的數和碼

與十進制一樣,二進制數與二進制碼也有類似的差別。隻不過在二進制中,隻能用數字0和1組成的位串來表達任何大小的數值或者表示具有任何含義的碼。

(1)一位二進制的數和碼

如果用單個位來表示整數值,隻能直接表示0和1這兩個值中的一個。如果用單個“位”來表示碼,則能夠用來對任何(同屬一種類型的)兩種不同僚物制定編碼規則。比如,用0表示“假”, 用1表示“真”;用0表示狀态“關”,用1表示狀态“開”; 用0表示“是”,用1表示“否”;用0表示“取物品”, 用1表示“存物品”;用0表示“黑”,用1表示“白”等。

(2)兩位二進制的數和碼

如果用長度為2的一個位串來直接表示整數值,則隻能夠表示00(其值等于0)、01(其值等于1)、10、11這4個二進制非負整數值中的某一個。如果用長度為2的位串來進行編碼,由于一共有00、01、10、11這4(即22)個碼值可以使用,則能夠用來對屬于同一類型的4個不同的事、物(或狀态)制定編碼規則。比如,{煎,炒,蒸,煮 }、{加,減,乘,除}、{班主任,老師,家長,朋友}、{a,b,c,d}、{–2,–1,0,1}、{宿舍,教學樓,食堂,圖書館}、{向左,向右,前進,後退}等,都可用長度為2的二進制碼來間接表示。

【例題1.1】編碼和解碼的一個執行個體。

通過制定一個編碼規則,比如,規定用00表示“d”、01表示“c”、 10表示“b”、11表示“a”,就可以構成一張用4個碼來表示4個字元的編碼解碼表,見表1-2。

用嚴格的數學術語來講,所謂制定編碼規則,就是規定了一張兩個集合{00,01,10,11}與 {a,b,c,d} 之間的所有元素的一對一的映射表而已。

表1-2 4個字元的一張編碼解碼表

《C語言程式設計:問題與求解方法》——1.1節二進制簡介

有了這張編碼解碼表,對字元串“cab”進行編碼後,就可以用碼值構成的二進制位串“011110”,在二進制的數字信号處理裝置中間接地存儲和傳輸這個字元串。

到達目的地後,接收方也要具有同樣的一張“字元編碼解碼表”,才能将接收到的二進制位串翻譯成它的本來意義。比如将二進制位串011110翻譯成字元串“cab”,這個過程稱為解碼。

(3)長度為n的二進制的數和碼

長度為n的位串可以表示的最大二進制非負整數111…1(一共n個1)究竟是多大呢? 這很簡單,将由n個1構成的此二進制數加上1,可得到100…0(1的後面一共有n個0)。由這個數的多項式展開可知,它的大小就是2n。是以二進制整數111…1(一共n個1)的大小為2n–1。

是以,如果用長度為n的位串來直接表示一個非負整數,則可以表示的二進制數值從小到大依次是0、1、10、11、…、1111…11(一共n個1,其值等于2n-1),一共有2n個數,則能夠用來對任意的2n個同類事物所構成的集合制定一對一的編碼規則。

3.世上的絕大多數事物都可通過編碼來間接表示

用一個位串隻能夠直接表示一個非負整數,有符号整數都不能直接用位串來表示。但是,用位串作為碼可以間接表示事物的種類卻是無限的,世界上的一切可數的事物都可以用碼來間接表示,不可數的事物可以用碼來近似表示(如何用位串來表示實數、圖像和聲音請參見後面的内容)。

延伸與拓展:

無效碼(或稱為非法碼)

在可使用的碼比(要進行編碼的)集合中的元素多的情況下,就會存在一些無效碼,這些無效碼不代表集合中的任何一個元素。究竟哪些是無效碼,是由具體編碼規則決定的。

比如用長度為3的位串來對某個集合(中的所有元素)進行編碼,可用的碼值一共有8(即23)個,集合中如果隻有5個元素,那麼必然有3個碼是無效碼。

一般情況下,長度為n的位串一共有2n個碼,如果用來對m個元素構成的集合進行編碼,而且2n大于m,則總共有2n–m個無效碼。

不定長度編碼

還有一種碼的長度不一樣的編碼方式,常常用比較短的碼表示集合中經常出現的元素。比如哈夫曼編碼就是一種不定長度的編碼,詳細内容請參見相關文獻。

4.ascii碼表

英文檔案中出現的常用字元,不僅有26個大小寫英文字元,還有10個阿拉伯數字字元,另外還有一些用作标點符号的字元(“,”,“.”,“!”等),所有這些字元加上通信過程中需要使用的符号和表示計算機輸入輸出裝置動作的一些特殊空白字元(比如回車、換行、倒退等)一共有128個。對于這些字元構成的集合,可用長度為7位的二進制進行編碼,曆史上曾有多種編碼方案,現代最常用的是ascii編碼解碼表(簡稱ascii碼表),即美國資訊交換标準代碼(參見附錄b)。

下面将簡要介紹計算機的基本工作原理,為讀者學習用進階語言程式設計奠定堅實的理論基礎。對計算機工作原理更深入一步的講解請參見第11章。

繼續閱讀