如靜制動 如影隨形
[1] 編程所需兩種基本能力
接口的封裝和設(shè)計能力(功能抽象分封裝)
1)接口api的使用能力
2)接口api的查找能力(快速上手)
3)接口api的實現(xiàn)能力建立正確程序運行內(nèi)存布局圖(印象圖)
1)建立內(nèi)存四區(qū)模型圖
2)函數(shù)調(diào)用模型圖
[2]內(nèi)存四區(qū)(堆谁榜、棧、全局區(qū)、代碼區(qū))
綜述
在C語言程序中,代碼在內(nèi)存中進(jìn)行執(zhí)行的時候,我們粗略的將程序所占的內(nèi)存分為四個區(qū)域---棧區(qū)雅宾,堆區(qū)、全局區(qū)、代碼區(qū)侥涵。每個程序都有唯一的四個內(nèi)存區(qū)域。我們需要熟悉和了解各個區(qū)域的特性,例如存儲什么類型的數(shù)據(jù), 有誰去申請開辟, 又有誰去管理釋放等等宋雏。內(nèi)存四區(qū)介紹
<1>棧區(qū)
由編譯器自動分配釋放芜飘,存放函數(shù)的參數(shù)值,局部變量等磨总。
例如: 參數(shù)buf,參數(shù)bufsize和size都是存放在棧區(qū).當(dāng)函數(shù)執(zhí)行完畢的時候,自動釋放
void recev(char* buf, int bufsize){
int size;
}
<2>堆區(qū)
一般由程序員分配釋放(動態(tài)內(nèi)存申請與釋放)嗦明,若程序員不釋放,程序結(jié)束時可能由操作系統(tǒng)回收蚪燕。
例如:下面的src所指向的內(nèi)存空間就是在堆區(qū)
char* src = (char*) malloc(sizeof(buf) * sizeof(10));
<3>全局去(靜態(tài)區(qū))
全局變量和靜態(tài)變量存放在此娶牌。里面細(xì)分有一個常量區(qū), 字符串常量和其他常量也存放在此. 該區(qū)域是在程序結(jié)束后由操作系統(tǒng)釋放奔浅。
<4> 程序代碼區(qū)
這個區(qū)域存放函數(shù)體的二進(jìn)制代碼.也是由操作系統(tǒng)進(jìn)行管理的
[3]劃分內(nèi)存四區(qū)的意義
- C語言程序中,根據(jù)是局部變量,全局變量, 常量還是通過malloc等類似的函數(shù)分配內(nèi)存空間, 把他們放到對應(yīng)的內(nèi)存區(qū)中.這樣就賦予了這些變量或常量不同的生命周期, 不同的釋放方式. 根據(jù)我們程序的需要,我們在編碼過程中,聲明不同的變量類型, 使他們有不同的聲明長度, 不同的釋放方式,給我們更大的靈活編程
[4]內(nèi)存四區(qū)的一個示例
- 四區(qū)代碼如下
(1)棧區(qū)
棧區(qū)的變量由編譯器自動分配釋放,存放函數(shù)的參數(shù)值诗良,局部變量等汹桦,函數(shù)推出后變量自動被釋放。下面的程序中鉴裹,getMem()
在棧中分配了個數(shù)組變量buf
舞骆,在main
函數(shù)調(diào)用中將其賦值給temp
,這里會使得程序出錯甚至崩潰径荔。原因在于getMem()
退后后變量buf
被釋放掉了督禽,temp
指向了一個被釋放的內(nèi)存空間。
char *getMem()
{
char buf[64]; //臨時變量 棧區(qū)存放
strcpy(buf, "123456789");
//printf("buf:%s\n", buf);
return buf;
}
//main調(diào)用
void main()
{
char *tmp = NULL;
tmp = getMem(10);
if (tmp == NULL)
{
return ;
}
}
(2)堆區(qū)
一般由程序員分配釋放(動態(tài)內(nèi)存申請與釋放)猖凛,若程序員不釋放赂蠢,程序結(jié)束時可能由操作系統(tǒng)回收。這里不會出現(xiàn)向棧的情況辨泳,原因在于堆中的內(nèi)存不會被自動釋放掉虱岂。
//堆
char *getMem(int num)
{
char *p1 = NULL;
p1 = (char *)malloc(sizeof(char) * num);
if (p1 == NULL)
{
return NULL;
}
return p1;
}
(3)全局區(qū)
全局變量和靜態(tài)變量存放在此。該區(qū)域是在程序結(jié)束后由操作系統(tǒng)釋放菠红。
char *getStr()
{
char *p = "abcdefg2";
return p;
}
void main()
{
char *p1 = NULL;
p1 = getStr();
}