前面咱們介紹了《深刻理解計算機系統》第一章的內容----計算機系統漫遊。包括簡單介紹了 Hello World 程序在計算機中是如何運行的,存儲設備的層次結構以及操做系統的抽象概念。第一章的內容只是對不少概念有個簡單瞭解,因此仍是不懂的話也沒關係,後面都會對這些概念進行深刻的探究。而這一章咱們將介紹《深刻理解計算機系統》第二章----信息的表示和處理。算法
程序=數據結構+算法,因此瞭解數據結構對咱們寫程序是很是有幫助的,這一章會詳細探討計算機數據的存儲和表示,其中也會有大量的公式推導。不要懼怕看不懂,LZ 有不少也是第一遍看不懂,可是後面慢慢推導,多看幾遍就看懂了,相信只要具有了高中代數知識的都能看懂。並且瞭解這些知識以後,你會發現你之前的程序代碼不少都不嚴謹,彷彿在你程序生涯中從新打開了一扇窗。編程
那麼多的不說了,這篇博客咱們就來看看計算機中信息的存儲和表示。數組
什麼是信息?信息是客觀事物屬性的反映,是通過加工處理並對人類客觀行爲產生影響的數據表現形式。網絡
那麼咱們這裏也要提一下什麼是數據,數據是反應客觀事物屬性的記錄,是信息的具體表現形式。任何事物的屬性都是經過數據來表示的,數據通過加工處理後成爲信息,而信息必須經過數據才能傳播,才能對人類產生影響。數據結構
例如,數據二、四、六、八、十、12是一組數據,其自己是沒有意義的,但對它進行分析後,就可獲得一組等差數列,從而很清晰的獲得後面的數字。這便對這組數據賦予了意義,稱爲信息,是有用的數據。大數據
計算機內全部的信息均以二進制的形式表示,也就是由值0和值1組成的序列。大多數計算機使用8位的塊,或者說字節("位(bit)"是電子計算機中最小的數據單位,每一位的狀態只能是0或1。8個二進制位構成1個"字節(Byte)"),來做爲最小的可尋址的存儲器單位,而不是在存儲器中訪問單獨的位。編碼
也就是說咱們訪問計算機最小的單位是八個位構成的字節,而不是值0或值1的單個位。spa
程序會將存儲器視爲一個很是大的字節數組,稱爲虛擬存儲器(virtual memory)。存儲器的每個字節都由惟一的數字來標識,也就是咱們說的地址(address),全部可能地址的集合稱爲虛擬地址空間(virtual address space)操作系統
好比 C 語言中的一個指針的值,不管它是指向一個整數、一個結構或是某個其餘程序的對象,都是某個存儲塊的第一個字節的虛擬地址。翻譯
編譯器和系統運行時是如何將存儲器空間劃分爲更可管理的單元,用來存放不一樣的程序對象。這個後面會詳細介紹。
一個字節由 8 位組成。在二進制表示法中,它的值域爲 00000000——11111111;若是用十進制表示就是0——255。這兩種表示法用來描述計算機中的位模式(計算機中全部二進制的0、1代碼所組成的數字串)來講都不是很方便。二進制表示法太冗長,而十進制表示法與位模式的互相轉化又比較麻煩。這時候 十六進制數產生了,十六進制使用數字‘0’~‘9’,以及字符 ‘A’~'F’來表示16個可能的值。通常是 0x 或者 0X 開頭。規則是:借一當十六,逢十六進一。
好比十進制數 175,咱們用十六進制表示爲 0xAF。
十六進制與十進制、二進制之間的互相轉換這裏就不詳細講解了,相信瞭解編程的對這個應該是很熟悉了。
計算機進行數據處理時,一次存取、加工和傳送的數據長度稱爲字(word),一個字一般由一個或多個(通常是字節的整數位)字節構成,字的位數叫作字長(word size),每臺計算機都有一個字長,用來指明整數和指針數據的標稱大小(nominal size)。因爲虛擬地址空間中的地址就是使用一個字來編碼的,所以字長決定了系統的虛擬地址空間的最大大小。
通俗來說:字長是CPU的主要技術指標之一,指的是CPU一次能並行處理的二進制位數,字長老是8的整數倍,一般PC機的字長爲16位(早期),32位,64位。
好比:LZ 打開命令提示符,而後輸入 systeminfo,能夠看處處理器的位數是 64 位
也就是說 LZ 的電腦字長爲 64 位,不過如今基本上 CPU 都是64 位的,可是爲了發揮64位字長的優點,咱們必須與64位軟件相輔相成,好比你得安裝64位操做系統,不然的話,在32位軟件系統中64位字長的CPU只能當32位用。
計算機和編譯器支持多種不一樣方式編碼的數字格式,好比整數和浮點數,以及其它長度的數字。並且因爲計算機位數的不一樣,會形成計算機在各類數據類型分配的字節數不同。下圖是 C 語言在 32位機器和64 位機器上各類類型所分配的字節數對比。
咱們能夠看出,對於長整形( long int)以及字符指針類型(char *)來講,在32位和64位系統下的字節數是不一樣的。因此在編程時,考慮到系統的移植性,這是咱們必需要考慮的。
注意:對於指針類型,因爲指針指向的是地址,而虛擬空間的大小是由字長決定的。因此在32位系統下,指針大小爲4個字節,在64位系統下,指針大小爲8個字節。
對於跨越多個字節的程序對象(程序對象指指令、數據或者控制信息等,是程序當中對象的統稱)來講,咱們須要制定兩個規則:
①、這個對象的地址是什麼?
②、在存儲器中如何排列這些字節?
在幾乎全部的機器上,多字節對象都被存儲爲連續的字節序列,對象的地址爲所使用字節中最小的地址。
好比:假設一個類型爲 int 的變量 x 地址爲 0x100,也就是說地址表達式 &x 的值是 0x100,那麼,x 的 4 個字節將被存儲在存儲器的 0x100,0x101,0x102,0x103的位置。
第一個規則解決了,那麼第二個規則如何排列呢?採用以下兩種方式:
小端法:按照從最低有效字節到最高有效字節的順序存儲對象,也就是最低有效字節在最前面。
大端法:和小端法相反。是按照從最高有效字節到最低有效字節的順序存儲對象,也就是最高有效字節在最前面。
回到上面的變量 x,若是假設 x 的低位字節值到高位字節值分別爲 67,45,23,01。那麼用大端法和小端法表示分別以下:
因爲排列字節的方式有兩種,那麼這就產生問題了。好比當小端法機器產生的數據被髮送到大端法機器或者反方向發送的時候就會發現,接收程序裏的字節成了反序。
爲了不這種狀況,網絡應用程序的代碼編寫必須遵循已創建的關於字節順序的規則,以確保發送方機器將它的內部表示轉換成網絡標準,而接收方機器則將網絡標準轉換爲它的內部表示。
上面咱們在講解第4小點數據大小時,咱們給出了 C 語言中不少的數據類型。那麼數據類型究竟是什麼呢?
程序編碼中,計算機是不認識咱們所定義的數據類型的。數據類型的出現是爲了把數據分紅所需內存大小不一樣的數據,編程的時候須要用大數據的時候才定義大數據類型,而後編譯器編譯標記須要申請大內存,就能夠充分利用內存。 例如大胖子必須睡雙人牀,就給他雙人牀,瘦的人單人牀就夠了。
那麼咱們能夠根據上面的尋址和字節順序得出,計算機在解釋一個數據類型的值時主要有四個因素:位排列規則(大端或者小端)、起始位置、數據類型的字節數、數據類型的解釋方式。
對於特定的系統來講,前兩種因素都是特定的,而對於後兩種因素的改變,則能夠改變一個數據類型的值的最終計算結果,這就是強制類型轉換。對於大部分高級程序設計語言來說,都提供了強制類型轉換。強制類型轉換有時候會讓結果變的讓人難以預料,因此咱們須要慎用。
在計算機中,對非數值的文字和其餘符號進行處理時,要對文字和符號進行數字化,即用二進制編碼來表示文字和符號。其中西文字符最經常使用到的編碼方案有ASCII編碼和EBCDIC編碼。對於漢字,我國也制定的相應的編碼方案,好比 GBK,GB2312等。
好比字符 ‘a’ 的 ASCII 碼十進制值爲 97,在計算機中用二進制表示就是 01100001
程序其實就是一個二進制序列的簡單描述,編譯器會幫咱們將其翻譯成對應的機器所認識的二進制序列。
本篇博客主要講解了信息在計算機中是如何存儲和表示的,須要注意的是咱們訪問計算機最小的單位是八個位構成的字節,而不是值0或值1的單個位。下一篇博客咱們將介紹布爾代數以及C語言中的位運算。