1、用變量名來訪問內存(c語言對內存地址的封裝、數據類型、函數名)--直接訪問內存(使用地址)
如 int a; 編譯器將申請32bit的內存(4個內存單元),同時將內存地址和變量名a綁定,操作a時,編譯器根據a綁定的地址去尋找對應的內存單元,我們則無需再關注具體的內存地址了。所以變量名被編譯器綁定上了地址。
數據類型:表示一個內存格子的長度和解析方法。(內存編址的單位是一個字節)
(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個內存單元格中,其存儲的內容沒變,還是1對應的2進制,但是本來是以int方式解析的,現在被強制轉換成以float方式解析,如果是(short)a;就是short類型解析以a開頭的連續2個內存單元,對另外兩個內存單元不作解析
函數名含義:函數本身就是一段代碼的封裝,函數名的含義是一段代碼的首地址,本質就是內存地址。
2、用指針間接訪問內存
關於類型(不管是普通變量類型int float等,還是指針類型int * float *等),只要記住:
類型只是對后面數字或者符號(代表的是內存地址)所表征的內存的一種長度規定和解析方法規定而已。
int a; // 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字節中存儲了1個地址,這個地址所代表的內存單元中存放的是一個int類型的數)。
3、數組管理內存:
數組管理內存和變量其實沒有本質區別,只是符號的解析方法不同。(普通變量、數組、指針變量其實都沒有本質差別,都是對內存地址的解析,只是解析方法不一樣)。
int a; // 編譯器分配4字節長度給a,並且把首地址和符號a綁定起來。
int b[10]; // 編譯器分配40個字節長度給b,並且把首元素首地址和符號b綁定起來。