型別的本質:對變數、型別、指標的理解

機智的小小帥發表於2021-06-19

核心觀點:型別約定了對資料的解釋方式

資訊和資料

來自 wikipedia 的定義

https://en.wikipedia.org/wiki/Information

https://en.wikipedia.org/wiki/Data

wikipedia 上的定義真的是太晦澀了

在我的理解中,資料就是不帶有任何屬性的數字。例如一個數字1,就是一個單純的資料。

僅通過一個數字 1,你是無法得到任何資訊的,因為你不知道這個1到底代表什麼意思。只有結合具體的語境,你才能從中獲得有用的資訊。

例如1本書、1個人、1頭豬等等

上面的書、人、豬實際上就是對資料的解釋方式。他們分別將 1 解釋為書的數量、人的數量、豬的數量。

因此為了獲取資訊,除了知道資料本身外,你還得需要知道對資料的解釋方式。

所以,資訊 = 資料 + 資料的解釋方式

想一想諜戰片子裡面的電報機,電報機所傳送的實際上是一些長短不一的摩爾斯電碼,這些摩爾斯電碼就是資料,外部人員不知道這些電碼代表的是啥,但是專業的諜報人員對其翻譯後,就可以從其中獲取到有用的資訊。這裡的翻譯實際上就是在對資料進行解釋。翻譯工作可能是依靠一個密碼本來進行的,密碼本上約定了資料的解釋方式。

例子
l i v e

這四個字母,如果用從左至右的方式來解釋,將是 live,如果用從右至左的方式來解釋,將是 evil。

1 0 1 1

這四個數字,如果每兩個一組進行解釋,將會得到

10 11

如果每四個一組進行解釋,將會得到

1011

同樣的資料,使用不同的解釋方式,就能得到不一樣的資訊。

型別約定了對資料的解釋方式

c 語言中有如下一些基礎資料型別,摘自https://www.runoob.com/cprogramming/c-data-types.html

整數型別

型別 儲存大小 值範圍
char 1 位元組 -128 到 127 或 0 到 255
unsigned char 1 位元組 0 到 255
signed char 1 位元組 -128 到 127
int 2 或 4 位元組 -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647
unsigned int 2 或 4 位元組 0 到 65,535 或 0 到 4,294,967,295
short 2 位元組 -32,768 到 32,767
unsigned short 2 位元組 0 到 65,535
long 4 位元組 -2,147,483,648 到 2,147,483,647
unsigned long 4 位元組 0 到 4,294,967,295

浮點型別

型別 儲存大小 值範圍 精度
float 4 位元組 1.2E-38 到 3.4E+38 6 位小數
double 8 位元組 2.3E-308 到 1.7E+308 15 位小數
long double 16 位元組 3.4E-4932 到 1.1E+4932 19 位小數

再回顧一下我的核心觀點:型別約定了對資料的解釋方式

在這裡我就取 char 型別和 short 型別來解釋。char 型別的大小是 1 位元組,short 型別的大小是 2 位元組。一位元組 byte 等於 8 bit,一個 bit 就是一個二進位制位,值為 0 或 1。實際上 char 約定了以 8 個 bit 為一組來解釋,而 short 則約束了以 16 個 bit 為一組來解釋。

現在有一個 16 個 bit 大小的空間,空間裡的內容為:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1

如果用 char (每 8 個 bit 為一組)來解釋,則可以解釋為兩個 char,char0 = 00000000 = 0,char1 = 00000001 = 1。

如果用 short (每 16 個 bit 為一組)來解釋,則可以解釋為 1 個 short,short0 = 0000000000000001 = 1。

變數(variable) = 地址(address) + 型別(type)

一個變數由兩個要素組成,分別是變數的地址,以及變數的型別。

address 確定了存放變數的字面值的空間位置

type 約定了如何解釋這段空間

在 c 語言中,初始化一個變數的方式是:

char a = 1;

例如在這裡,

  • 變數 a 的 address 是 &a
  • 型別是 char,它決定了將會以 8 個 bit 為單位解釋 address 中的內容
  • a 的字面值是 1,字面值是通過 address 和 char 通過得到的

在 address 處存放了資料本體,利用 type 來解釋資料,最終得到字面值這個資訊。

對變數的訪問是通過訪問該變數的地址來完成的

在 c 語言中,對於變數的訪問實際上都是通過訪問該變數的地址來完成的。但是隻有地址還不夠,如何解釋這篇地址的內容,是以 8 個 bit 為單位亦或者是以 16 個 bit 為單位,這就需要用到型別了。

變數在初始化時,會被分配一個地址。這個地址就是變數的家,變數的地址是不會發生改變的,它一輩子只會有一個家,不會搬家。

變數的初始化
char c = 1;

在這行程式碼裡,實際上會有如下兩步操作:

  1. 為變數 c 分配一個空間,這個空間就是 c 的家,假設 c 住在地球一號村,二號樓0號房間吧,就用 0x120 來表示 c 的地址吧。

  2. 將 0x120 ~ 0x128 這 8 個 bit 的空間裡的內容初始化為 1(其實 c 裡面地址的單位是 1 個 byte,而非 bit),變成下面這個樣子:

    image

    為何是 8 個 bit 而不是其他數字的 bit?這是 c 的型別所決定的,因為型別是 char,所以是 8 個 bit。

對 c 的修改
c = 2

實際上還是分為兩步:

  1. 第一步還是先得到 c 的地址,之前說過變數的地址是不會傳送改變的,因此這裡變數 c 的地址也就是 0x120

  2. 將 0x120 ~ 0x128 這 8 個 bit 的空間裡的內容初始化為 2,變成了下面這樣:

    image

對 c 的訪問
char i = c;
  1. 得到 c 的地址 0x120
  2. 對 0x120 ~ 0x128 這 8 個 bit 大小的空間進行解釋。型別約定了對資料的解釋方式,而這裡的型別是 char,所以用 8 個 bit 的方式來解釋。
  3. 對 i 的操作也是類似的...

指標

指標變數本質和普通的變數沒有太大區別,依舊由值和型別組成,同樣也會被分配一個地址。

但是它相比普通變數多了一個 * (dereference) 操作。dereference 是指標變數所特有的操作,普通的變數是無法進行 dereference 操作的,否則會發生編譯錯誤。

定義一個指標變數
char* p = 0x120;

p 的值是 0x120 ,p 的型別是 char* (指向 char 型別的指標)。

char* = char + *
* 表明這個變數是一個指標,因此有 dereference 能力
char 約定了在 dereference 時,它將會以 8 個 bit為 單位來解釋
deference

通過 dereference ,可以對地址中的內容進行操作。

*p = 1

這句程式碼將會把 0x120 ~ 0x128 這 8 個 bit 的空間裡的內容置為 1。

image

對指標變數的修改
p = 2

與上面所說的變數的修改過程是一樣。

一些具體的例子

基本原則
  1. 變數 = address + type
  2. 變數會被分配一個地址,且這個地址是固定的
  3. 對變數的訪問是通過訪問變數的地址來完成的,變數的型別約定了對地址中內容的解釋方式
例子1:通過指標來修改變數的值
char c = 1;			// 為 c 分配地址,假設 c 的地址是 0x120,c 的值是 1,0x120 ~ 0x128 這 8 個 bit 的內容是 1
char* pc = &c;		// pc 是一個指標,它的值是 c 的地址,則 pc 的值是 0x120
*pc = 2;			// dereference 操作,將 0x120 ~ 0x128 這 8 個 bit 的內容設定為 2
printf("%d",c);		// 取 0x120 ~ 0x128 這 8 個 bit 的內容進行解釋,得到 2,因此輸出 2
例子2:指向指標的指標
char* pc = null;	// 為 pc 分配地址,假設 pc 的地址是 0x1200,pc 的值是 0,0x1200 ~ 0x1220 這 32 個 bit 的內容是 0(在 32 為環境下,指標的大小是 32 bit)
char** ppc = &pc;  // ppc 的值為 0x1200
char c = 1;		   // 為 c 分配地址,假設 c 的地址是 0x120,c 的值是 1,0x120 ~ 0x128 這 8 個 bit 的內容是 1
*ppc = &c;		   // 將 0x1200 ~ 0x1220 這 32 個 bit(char*) 的內容設定為 0x120,此時 pc 的值為 0x120 了
*pc = 2;		   // 取 0x120 ~ 0x128 這 8 個 bit(char) 的內容設定為 2, 此時 c 的值變成 2 了

相關文章