記憶體管理藝術3(基于C語言)
---------C語言如何操作記憶體?
資料類型----長度和解析方法
基于朱有鵬C語言進階視訊總結
1、C語言對記憶體位址的封裝(用變量名來通路記憶體、資料類型的含義,函數名的含義)
寄存器其實就是記憶體,
結合記憶體來解析C語言語句的本質:
Int a; //編譯器幫我們申請了1個int類型的記憶體格子(長度是4位元組位址隻有編譯器知道,我們肯定是不知道的)并且把符号a和這個格子綁定。
變量名和記憶體位址一一定義了;
C語言中資料類型的作用:
表示一個記憶體格子的長度和解析方法:
很多同學不了解強制類型裝換:
本質上是沒有改變的:
(Int* )0 代表的是一個記憶體的位址0
我們認為這個是一個0位址的指針,隻不過這裡面存放的是一個整形的數。
資料類型決定長度的含義:我們一個記憶體位址(0x30000000),本來這個位址隻代表1個位元組的長度但是實際上我們可以通過給他一個類型,讓他有了長度,這樣這個代表記憶體位址的數字就能表示從這個數字開頭的連續N個位元組的記憶體格子了。
之前講過一個很重要的過概念,記憶體單元的格子的遍址的單元是位元組。
資料類型還能夠解析方法:
比如我有一個記憶體位址(0x30000000),我們可以通過給這個記憶體位址不同的類型來指定這個記憶體單元格子中的二進制數的解析方法,比如我給他一個int型
(int)0x3000000 和(float) 0x30000000 這裡面解析方法是不一樣的。
函數名:
函數在C語言裡面,函數就是一段代碼的封裝,函數名的實質,就是這一段代碼的首位址。
2、用指針來間接的通路記憶體
在C語言可以用間接通路記憶體,也涉及到我們掌握的資料類型,
關于類型:
不管是普通的變量類型int float等,還是指針類型int* float*
隻要記住:
(1)類型隻是對後面的數字或者符号(代表的都是記憶體的位址)所表征的記憶體的一種長度規定和解析方法。
(Int*) 0;
(int *)a; a和0其實是沒有本質的差別的,就是a會由編譯器随機的配置設定一個位址。
(2)C語言中的指針,全名叫做指針變量,指針變量其實和普通變量沒有任何的差別,比如int a 和int *p 其實是沒有任何的差別的,a和p都代表一個記憶體位址,但是這個記憶體位址的解析方法不一樣,但是這個記憶體位址(0x20000000)的長度和解析方法不同,a是int型是以a的長度是4位元組,p是int* 類型,解析方法是按int *的規定來的(0x20000000開頭的連續4個位元組中存儲了1個位址,這個位址所代表的記憶體單元中存放的是一個int類型的數)。
3、用數組來管理記憶體
數組管理記憶體其實和變量沒有本質差別,隻是符号的解析方法不同。(普通變量、數組、指針變量)差别就是他們的符号的解析方法不一樣,都是對記憶體位址的解析,有長度都是要涉及到長度和變量。
有些記憶體有一個互相呼應的過程。
4、記憶體管理之結構體:
資料結構這門學問的意義;
資料結構就是研究資料在記憶體中如何排布?
如何加工,資料就得放在記憶體當中,如何加工的學問。
最簡單的資料結構是數組:
因為程式中有好多個類型相同、意義相關的變量需要管理,這時候如果用單獨的變量來做程式看起來比較亂,用數組來管理會更好的管理。
比如說定義一個int ages[20]; 我要管理一個班的20個學生的年齡。
數組的優勢和缺陷:
優勢:數組比較簡單,通路用下标,可以随機通路。
缺陷:1、數組中所有元素的類型必須相同。
2、數組的大小必須在定義時給出,而且一旦确定不能再改。
數組是不具有伸縮性。
這個程式給出的靈活性就比較差了。
結構體的隆重登場:
1、結構體發明出來,就是為了解決第一個缺陷的。
我們要管理三個學生的年齡,
第一種解法:我要用數組, int ages[3];
第二種解法:我用結構體:
Struct ages
{
Int age1;
Int age2;
Int age3;
};
Struct ages age;
分析總結:在這個示例中數組要比結構體好。在元素類型不同的時候就隻能使用結構體了,不能使用數組了。
整個一個結構體裡面的成員變量的長度是不一樣的,是以說結構體裡面,隻能用.的方式來通路到每一個元素的位址。
怎麼在記憶體裡面尋址?
題外話:結構體内嵌指針實作面向對象:
面向過程和面向對象,
總的來說:C語言是面向過程的,但是C語言寫出的linux系統是面向對象的。
非面向對象的語言,不一定不能實作面向對象的代碼,隻是說用面向對象的語言來實作面向對象更加簡單,直覺一些,無腦一些。
用C++和JAVA等面向對象的語言實作面向對象簡單一些,因為語言本身幫我們做了很多事情,但是用C來實作面向對象很麻煩,看起來也不容易了解。
有一個類,有一個成員變量和方法。
這樣包含了函數指針的結構體就相當于面向對象中的class,結構體中的變量類似于class中的成員變量,結構體中的函數指針類似于class中的成員方法。