第六章:C語言之「內存管理」,論如何通俗易懂地學習C語言
前幾節內容主要和大家講的是C語言中一些數據類型和一些基本的用法,也和大家交流了如何去理解MCU的工作步驟,我個人覺得這種用人去和MCU類比的方式非常便於大家的理解,在寫程序時,所要設計的演算法也確實是先基於我們人自己的執行流程,然後講這種流程通過C語言表達而已,我們所要做的就是正確地使用好C語言的語法,要不然是無法編譯成功的,就算編譯成功也不能按照你所設計地流程執行。
那麼除了正確地使用使用好C語言,還有一點是非常重要的,這個問題很難發現,但是如果出現這樣的情況,程序很有可能運行不了,也有可能出現意想不到的結果,而我們的程序猿經常需要花費很長的時間去尋找這個問題,關鍵是最後只需要稍作修改就可以,這著實很讓人懊悔。
Advertisements
沒錯那就是我們沒有合理的使用內存。那麼,什麼是內存?我們前面和大家講過內存很是寶貴,程序的運行和變數的創建都是需要用到內存的。程序和進程是不同的概念,程序我們是保存在Flash中的,這就像是我們把任務存放在記事本里,沒有必要時時刻刻放在腦海中,要不然不就佔用你大腦的存儲空間了嗎?同樣的,程序是不在內存中的,當你要執行任務時,你才會將從記事本里將任務提取到大腦中,並開始執行任務,執行任務的過程就是進程,這個時候在內存中運行的就是進程。任務中所要創建的變數也會存放在你的大腦中,同樣內存中也會產生相應的變數,這就佔用了內存。我們人腦記憶東西是有時間限制的,記住了一個東西只需要一段時間沒有複習就會忘記,但是我們的MCU可不會這樣,你知道MCU是機械性的,創建了他可不會自動把變數給清除了。在編程時,我們可不是單單用一些常規的變數類型,結構體、數組和鏈表這些大量佔用內存的類型是經常要是用的,那麼那點可憐的內存該如何使用呢?
Advertisements
不要擔心,辦法總是有的,既然他不會自動將空間騰出來,那我們就主動將那些沒用的變數清除了,要讓他們知道我們才是主人,沒有利用價值的東西,就該將位置空出來給其他變數使用。那麼我們該如何使用這一功能呢?我們平時創建一個變數時總是在內存中的隨機地址生成一個變數,但是這樣的變數是沒辦法消掉的。只有這樣操作我們才能在變數的使用價值結束后將位置騰出來,那就是我們先主動分配一個區域,我們得給這個區域打上「臨時地址的標籤」,然後將變數存儲在這片區域上,變數在使用完之後,我們就可以將這片「臨時區域」收回,那麼地址上的變數也會自動消失。 這樣就實現了分配——>使用——>收回 的機制。有了這種機制,空間才能得到充分地利用,那麼接下來就看看在程序中該如何使用C語言來實現這種功能。
常用的內存管理函數有以下三個:
1. 分配內存空間函數 malloc
調用形式:
(類型說明符*)malloc(size)
功能:在內存的動態存儲區中分配一塊長度為"size"位元組的連續區域。函數的返回值為
該區域的首地址。
「類型說明符」表示把該區域用於何種數據類型。
(類型說明符*)表示把返回值強制轉換為該類型指針。
「size」是一個無符號數。
例如:
pc=(char *)malloc(100);
表示分配 100 個位元組的內存空間,並強制轉換為字元數組類型,函數的返回值為指向該
字元數組的指針,把該指針賦予指針變數 pc。
2. 分配內存空間函數 calloc
calloc 也用於分配內存空間。
調用形式:
(類型說明符*)calloc(n,size)
功能:在內存動態存儲區中分配 n 塊長度為「size」位元組的連續區域。函數的返回值為該區域的首地址。
(類型說明符*)用於強制類型轉換。
calloc 函數與 malloc 函數的區別僅在於一次可以分配 n 塊區域。 (calloc和mallo還有一點區別,這個大家可以去思考一下)
例如:
ps=(struet stu*)calloc(2,sizeof(struct stu));
其中的 sizeof(struct stu)是求 stu 的結構長度。因此該語句的意思是:按 stu 的長度
分配 2 塊連續區域,強制轉換為 stu 類型,並把其首地址賦予指針變數 ps。
2. 釋放內存空間函數 free
調用形式:
free(void*ptr);
功能:釋放 ptr 所指向的一塊內存空間,ptr 是一個任意類型的指針變數,它指向被釋放區域的首地址。被釋放區應是由 malloc 或 calloc 函數所分配的區域。
例:分配一塊區域,輸入一個學生數據。
void main()
{
struct stu
{
int num;
char *name;
char sex;
float score;
} *ps;
ps=(struct stu*)malloc(sizeof(struct stu));
ps->num=102;
ps->name="Zhang ping";
ps->sex='M';
ps->score=62.5;
printf("Number=%d\nName=%s\n",ps->num,ps->name);
printf("Sex=%c\nScore=%f\n",ps->sex,ps->score);
free(ps);
}
本例中,定義了結構 stu,定義了 stu 類型指針變數 ps。然後分配一塊 stu 大內存區,並把首地址賦予 ps,使 ps 指向該區域。再以 ps 為指向結構的指針變數對各成員賦值,並用printf 輸出各成員值。最後用 free 函數釋放 ps 指向的內存空間。整個程序包含了申請內存空間、使用內存空間、釋放內存空間三個步驟,實現存儲空間的動態分配。
好了,今天就和大家分享到這裡,今天其實就是對大腦存儲系統的分析,合理地使用內存才能讓程序正常地執行。
其實C語言講到這裡也就是這些知識,從下一章開始就和大家開始一起實戰性學習了,我也不準備使用51單片機和大家一起學習,我準備使用目前主流的stm32單片機和大家一起學習,stm32的是目前性價比極高的一款MCU,功能強大,應用也非常的廣,太難的,我們也先不去學,但是太簡單的學習起來也沒啥意思,所以等待下一章和大家一起去探索stm32。
謝謝大家的陪伴。