萬盛學電腦網

 萬盛學電腦網 >> 網絡基礎知識 >> 1.2 數據在計算機中的存儲形式

1.2 數據在計算機中的存儲形式


1.2.1 位、字節、字的概念

  在主機內的存儲器,稱內存儲器,簡稱內存。要運行的程序和數據都存放在內存中。那麼內存是由什麼組成的呢?它原來是由千千萬萬個具有二個狀態的電子開關組成的。電子開關打開時的狀態為“1”,閉合時的狀態為“0”。每個電子開關用計算機術語“位(bit)”來稱呼,它可以代表二進制數(逢二進一)的一個基本單元。計算機內存就是一個龐大的二進制基本單元——電子開關的集合體。

  要存放信息,必須把這些電子開關有機地組織起來,一般用若干個二進制“位”組成一個“字節”(byte),多數計算機用8位組成一個字節,如圖1.1所示。

  一個字節可以存放一個字符,當然這個字符是用一個二進制數來表示的,這個二進制數就是這個字符的二進制代碼。計算機上所應用的全部字符(字母、數字或其他專用字符)都有相應的二進制代碼,如字母“a”,它的二進制代碼是:

  這些字符和二進制代碼之間的對應關系,很多計算機系統采用ASCII(American Standard Code for Information Interchange即“美國標准信息交換碼”)代碼。這個代碼與字符之間的對應關系見附錄I。

  計算機內存就是由很多排列整齊的字節組成,為了管理方便,每個字節都有相應的位置編號,這個編號就是這個字節的“地址”,通過地址可以找到內存中任何一個字節的內容。

  一個字節可以存放一個字符,但要存放一個整數或一個實數,一個字節就不夠了,有的系統上整數用2個字節或4個字節來存放,而實數用4個字節來存放。由一個或若干個字節組成一個“字”,一個字可以用來存放一個數據或一條指令。

  1.2.2 內存單元、內存單元地址和指針的概念

  一個內存單元可以用來存放一個數據或一條指令,由於內存中每個字節都有自己的地址,因此每個內存單元也有自己相應的地址,由一個字節組成的內存單元的地址,就是這個字節的地址,而由多個字節組成的內存單元的地址則指的是組成這個內存單元幾個字節中第一個字節的地址。假定程序中已定義了三個短整型變量i、j、z,編譯時系統分配給它們各一個內存單元,每個內存單元占兩個字節,如圖1.2所示,圖中每個長方形框代表兩個字節。如果分配給變量i的內存單元地址是5000(這只是假定的地址),那麼變量i占用地址為5000開始的兩個字節(即地址為5000和5001兩個字節),5000是變量i的內存單元地址,簡稱變量i的地址,C/C++語言中用符號“&i”表示,這裡&表示取地址,&i的值是5000。若定義變量時j是緊跟在變量i之後,變量z又緊跟在j之後,那麼系統分配給這些變量的內存單元一般是連續的,即分配給變量j的內存單元地址是5002,分配給z的內存單元地址是5004,所以變量j的地址&j的值是5002(變量j占用地址為5002和5003兩個字節),而變量z的地址&z的值為5004(變量z占用地址為5004和5005兩個字節),所以,當程序定義了某一變量以後,變量名和它占用的內存單元地址有直接的對應關系。

  請注意,要區別一個內存單元的地址和這個內存單元的內容(即變量值)這兩個概念。對變量值的存取是通過地址來進行的,根據變量名和地址的對應關系找到變量的地址,然後從這個地址所標識的存儲單元中進行存取數據的操作。圖1.2中,設變量i,j的值分別是5和3,要執行一個操作z=i+j時,過程是這樣的:從變量i存儲單元的地址5000開始的兩個字節中取出變量i的值5,再從變量j存儲單元的地址5002開始的兩個字節中取出變量j的值3,通過CPU將它們相加後得8送到變量z內存單元中,即送到地址為5004開始的兩個字節中。這種按變量地址存取變量的方式稱為“直接訪問”(即:直接尋址)方式,這裡的“訪問”指的是在內存單元中存取(或稱讀寫)數據的意思。

  總之,通過變量的地址能找到變量的內存單元,因此,把變量的地址稱作變量的“指針”,如地址5000是變量i的指針,地址5002是變量j的指針。通過變量的指針可以找到變量的內存單元來對變量進行讀寫操作。指針指的是某個內存單元的首地址(或說一個內存單元的入口地址),因此C語言中應用的指針是有數據類型的(詳見第2章),而每一種數據類型的變量在內存中存放的數據是以內存單元為單位的。

  與“直接訪問”相對應的另一種訪問內存的方式是“間接訪問”(即:間接尋址)方式。C語言中可以定義一種變量專門用來存放地址,假定我們定義一個變量i_pointer是用來存放整型變量地址的,系統編譯時分配給這個變量的地址假定是6020,那麼可以通過下面賦值語句將變量i的地址賦給變量i_pointer:

i_pointer=&i ;

  變量i的地址值是5000,所以通過以上賦值語句就把地址值5000放入地址是6020開始的兩個字節中,i_pointer的值就是5000。這樣,我們就可以對變量i進行間接訪問了,過程是:先從變量i_pointer中提取變量i的指針5000,然後到地址是5000和5001兩個字節中存取i的值。圖1.3表示直接訪問和間接訪問的示意圖。

  圖1.3(a)表示對變量i的值直接進行讀寫操作(直接訪問);圖1.3(b)表示對i_pointer所“指向”的內存單元進行讀寫操作(間接訪問)。因為i_pointer的值是變量i的地址,所以稱i_pointer指向變量i,借助於i_pointer可以對變量i進行讀寫操作。當i_pointer的值用變量j的地址&j重新賦值,那麼借助於i_pointer可以對變量j進行讀寫操作。因為i_pointer的值可以改變,所以稱它為“指針變量”。關於指針變量的定義詳見第2章,這裡只作概述,目的是說明借助於它訪問內存的方式(間接訪問的方式)。

  1.2.3 原碼、反碼和補碼的概念

  內存中的每一個數都占用一個內存單元,而這個內存單元中的最高位用來表征數的符號,以0代表正數,以1代表負數,其余各位代表數的絕對值。

  一個數的代碼有原碼、反碼和補碼三種表達方式。而正數的原碼、反碼和補碼的形式都相同,沒什麼差別,如一個短整數,在內存中占兩個字節,假定它們在內存中是並排的,則+8的原碼、反碼和補碼都具有如下的形式:

  請讀者注意,負數的原碼、反碼和補碼的表示形式是不同的,如-8的原碼是:

  負數的反碼規定:符號位不動,其余各位對原碼取反。如-8的反碼是:

  負數的補碼規定:符號位不動,其余各位對原碼取反,然後加1。也就是說,一個負數的補碼是它的反碼加1。如-8的補碼是:

copyright © 萬盛學電腦網 all rights reserved