c語言如何操作記憶體(資料型別、函式在記憶體中解析簡介)
資料型別:表示一個記憶體格子的長度和解析方法。(記憶體編址的單位是一個位元組)
(int *) 0; //0的地址存的是指標,指標指向一個int型別的數,資料型別int規定了記憶體格子長度:4位元組
(float *) 0; //0的地址存的是指標,指標指向一個float型別的數
(short ) 0; //0地址是short型別的變數,存的是short型別的數
(char ) 0; //0地址是char型別變數,存的是char型別的數
這四個只是型別不同,但都是0;0代表記憶體地址(人為指定的);資料型別只是決定了長度,儲存的內容(解析方法).
資料型別決定長度的含義:
我們一個記憶體地址(0x30000000),本來這個地址只代表1個位元組的長度,但是實際上我們可以通過給他一個型別(int),
讓他有了長度(4),這樣這個代表記憶體地址的數字(0x30000000)就能表示從這個數字(0x30000000)開頭的連續的n(4)個位元組的記憶體格子了,即
(0x30000000 + 0x30000001 + 0x30000002 + 0x30000003).
資料型別決定解析方法的含義:
譬如我有一個記憶體地址(0x30000000),我們可以通過給這個記憶體地址不同的型別來指定這個記憶體單元格子中二進位制數的解析方法:
譬如我(int)0x30000000,含義就是(0x30000000 + 0x30000001 + 0x30000002 + 0x30000003)這4個位元組連起來共同儲存的是一個int型資料;
那麼我(float)0x30000000,含義就是(0x30000000 + 0x30000001 + 0x30000002 + 0x30000003)這4個位元組連起來共同儲存的是一個float型資料.
解析方法舉例:
假設記憶體裡存著 int a;float a;都存著 0x1111 0101 1101 1011,解析的時候int可能從第一位就開始判斷符號位,之後的位數都代表數值;
而float可能從第一位後面斷開,前面當做符號位,後面作小數位,具體的解析方法可以看《計算機組成原理》,內容相同,解析方法不同而已.
對資料型別強制轉換的理解:
int a = 1;
(float)a; 其實地址a開頭的連續4個記憶體單元格中,其儲存的內容沒變,還是對應的2進位制,但是本來是以int方式解析的,現在被強制轉換成以float方式解析,
如果是(short)a;就是short型別解析以a開頭的連續2個記憶體單元,對另外兩個記憶體單元不作解析.
函式名含義:
函式本身就是一段程式碼的封裝,函式名的含義是一段程式碼的首地址,本質就是記憶體地址. 此外需注意由於函式在記憶體中的分佈方式並不是齊整的,所以函式指標並沒有++自增運算和—自減運算,類似於(void *)
2、用指標間接訪問記憶體 ---【間接訪問記憶體】
關於型別(不管是普通變數型別int float等,還是指標型別int * float *等),只要記住:
型別只是對後面數字或者符號(代表的是記憶體地址)所表徵的記憶體的一種長度規定和解析方法規定而已.
int a; // 編譯器會自動給a分配一個記憶體地址,譬如說是0x12345678
(int *)a; // 等價於(int *)0x12345678
(float *)a; //解析方法是以指標來解析的
C語言中的指標,全名叫指標變數,指標變數其實很普通變數沒有任何區別.
譬如int a和int *p其實沒有任何區別,a和p都代表一個記憶體地址(譬如是0x20000000),但是這個記憶體地址(0x20000000)的長度和解析方法不同:
a是int型所以a的長度是4位元組,解析方法是按照int的規定來的;
p是int *型別,所以長度是4位元組,解析方法是int *的規定來的(0x20000000開頭的連續4位元組中儲存了一個地址,這個地址所代表的記憶體單元中存放的是一個int型別的數).
3、陣列管理記憶體:
陣列管理記憶體和變數其實沒有本質區別,只是符號的解析方法不同.
(普通變數、陣列、指標變數其實都沒有本質差別,都是對記憶體地址的解析,只是解析方法不一樣).
int a; // 編譯器分配4位元組長度給a,並且把首地址和符號a繫結起來
int b[10]; // 編譯器分配40個位元組長度給b,並且把首元素首地址和符號b繫結起來.