前幾天在判斷 「值相同的兩個指針所指向的變量的值能夠不一樣 」 這句話時,發現本身對指針類型一些概念僅僅是記住告終論。因而查閱了一些資料,記錄一下一些與指針類型和指針類型轉化相關的知識。spa
一些用到的3d
開始以前,先來複習一些會用到的知識。指針
1.地址,字節,位code
位(bit)是電子計算機中最小的數據單位。每一位的狀態只能是0或1。blog
字節(Byte)是用於計量存儲容量的一種單位,每個字節由8位組成(1Byte = 8bit)。內存
地址能夠理解爲在一片內存中,每一個字節(Byte)的編號。編譯器
他們在內存中的關係能夠比做,內存是一棟大樓,字節(Byte)是大樓中的每一層,地址是樓層編號,位(bit)是每一層中的房間,每一層有8個房間。it
2.變量的內存io
編譯器根據變量的類型,在內存中申請一塊空間。例如32位與64位中 int 類型申請到4字節的空間,可理解爲編譯器申請了4層樓,做爲」辦公區域「。編譯
3.指針變量
指針是指程序數據在內存中的地址。在c語言當中,容許用一個變量來存放指針,這種變量稱爲指針變量。
指針變量類型的做用
1 int a; 2 int *p; 3 p = &a; 4 printf("%p %d\n",p,*p);
以上程序中,」&「操做符取出了變量 a 在內存空間中的首地址,然後經過 「 * 」 操做符取出首地址所在內存空間的數據。
前面咱們提到,存儲變量的內存,是由多個字節組成。而指針變量在只知道首地址(第一個字節的地址)的狀況下,就能找到a的內存區域。它是怎麼作到的?先來看看指針變量的聲明。
咱們在聲明一個指針變量的時候,會根據它將要指向的變量類型,聲明對應的類型,例如:
1 int a; 2 long b; 3 char c; 4 5 int *pa = &a; 6 long *pb = &b; 7 char *pc = &c;
無論是什麼類型的指針變量,所存的值都是地址(int類型的值)。那麼聲明不一樣類型的做用是什麼?答案是規定指針在內存中每次移動的字節數。
例如定義「int *pa = &a」,取值時,int類型佔4個字節,指針就從首地址開始移動,讀取4個字節。同理,short類型佔2字節,指針就移動2字節。經過聲明指針類型,告訴指針每次移動多少字節,來獲取變量的值。
值相同的兩個指針所指向的變量的值能夠不一樣
「值相同的兩個指針變量」,意思是兩個指針變量指向同一個首地址。可是若是指針變量的類型不一樣,由於指針移動的字節數量不一樣,就可能讀取出不一樣的數據。
要實現不一樣類型指針變量指向同一個地址,須要使用指針類型轉換。
1 short a = 1; 2 short *p1 = &a; 3 int *p2 = (int *)p1; 4 printf("%d %d",*p1,*p2);
以上例子將一個每次移動讀取2字節的 short 類型指針變量,轉化爲一個每次讀取4字節的int型指針變量。
接下來,咱們經過指針類型轉換,用同一個首地址,取出不一樣的值。
1 #include <stdio.h> 2 int main() 3 { 4 short c[2]; //等價於申請2個連續的內存空間,每一個空間2字節 5 c[0] = 1; //爲第一個short空間賦值爲1 6 c[1] = 1; //爲第二個short空間賦值爲1 7 short *p1 = c; //p1指向c[]首地址 8 int *p2 = (int *)p1; //p2指向c[]首地址,並強制轉換類型爲 int 9 10 printf("p1指向:%p\np2指向:%p\n",p1,p2); 11 printf("p1取出:%d\np2取出:%d\n",*p1,*p2); 12 return 0; 13 } 14
對應結果爲:
p1指向:000000000062FE30
p2指向:000000000062FE30
p1取出:1
p2取出:65537
根據二進制轉換得,10000000000000001 爲 65537。由此可驗證強制轉換前指針讀取2字節,轉化後讀取4字節。兩個指針指向的首地址相同,可是讀出了不一樣的結果。