C語言理論篇——帶你輕松玩轉(zhuǎn)指針與動態(tài)分配內(nèi)存

2019.12.11

1.什么是指針以及它的作用

儲存數(shù)據(jù)的內(nèi)存是一串連續(xù)的字節(jié)單元格,如圖

內(nèi)存圖解.png

每一個單元格都有自己的地址,而指針則是用來儲存某個地址的變量
那么我們什么時候需要用到指針呢?下圖作為引例
值改變.png

使用函數(shù)返回值可以實現(xiàn)一個值的改變瞬捕,而return只能返回一個值虱疏,改變兩個及以上的值便需要指針
地址詳解.png

說明:首地址是指第一個字節(jié)的地址毒涧,其實指針并沒有如圖所示的指向作用,那樣畫方便理解徙邻,指針就是地址排嫌,通過它可以間接訪問或修改所存的地址內(nèi)的值,依圖舉個例子鹃栽,可以將0x100(地址)理解為一個小區(qū)中的房間門牌號躏率,1(所存的值)當(dāng)做租客躯畴,而指針就是保安室(登記有所有門牌號即地址)民鼓,通過保安室可以查到門牌號,再使用一個*即登門拜訪
一個指針?biāo)加每臻g:64位系統(tǒng)占8個蓬抄,32位系統(tǒng)占4個

2.指針的類型

指針的運(yùn)算指針+i是指指針?biāo)傅刂废蛴乙苿?strong>i*sizeof(所指向的變量類型)
指針之間還可以作減法丰嘉,僅限于數(shù)組內(nèi),作差的結(jié)果是兩個地址間相差的元素個數(shù)
整型指針:int *a
字符指針:char *a
指針數(shù)組:int *a[5],一個大小為5嚷缭,每個元素都是指針
數(shù)組指針:int (*a)[5] 只能指向二維數(shù)組饮亏,且二維數(shù)組中的一維數(shù)組長度為5
如int a[3][5];
?int (*p)[5]=a;
常量指針:指向地址的值不能改變
int a=20,b=30;
int const *p=&a;const(常量)在前
*p=&b;//可以改變指針的指向關(guān)系
指針常量:指向關(guān)系不能變,值可以變
int *const p1=&a;*指針在前
*p1=50;//可以改變里面的值
誰在前誰不變
二級指針:?int**p;里面存的是一個一級指針的地址阅爽,指針本身是有地址的

二級指針圖解.png

二級以上的指針如圖類推
指針函數(shù):int *add();?先忽略*路幸,add()是個函數(shù),它的返回類型是int*指針(即地址)
函數(shù)指針:int (*p)(int ,int);?由于()的優(yōu)先級更高付翁,所以無法先忽略*简肴,所以從*開始讀,是一個指針百侧,它指向的類型是一個函數(shù)砰识,函數(shù)的返回類型是整型
函數(shù)名其實是一個指針常量,它指向該函數(shù)代碼的首地址
int minus(a,b);
p=minus;
(*p)(a,b);等價于minus(a,b)

☆補(bǔ)充說明:相信很多初學(xué)指針的小伙伴都有這樣的一個困惑佣渴,指針只能用地址來賦值辫狼,為什么常量字符串可以使用char* name="xiaoming",常量字符串為什么可以這樣賦值辛润,其實啊膨处,真正賦值給name的還是一個地址雙引號" "做了以下三件事:
1.在內(nèi)存中開辟了一片連續(xù)的空間
2.將常量字符串放進(jìn)去砂竖,并在末尾添加\0
3.最后返回那一片連續(xù)內(nèi)存空間的首地址
所以常量字符串的賦值不需要使用malloc為字符指針分配內(nèi)存空間灵迫,直接使用雙引號即可,這樣的表達(dá)是沒有任何問題的晦溪,這是指針中容易搞混的地方

3.指針和數(shù)組的關(guān)系

1.指針與一維數(shù)組之間可以相互轉(zhuǎn)換瀑粥,數(shù)組名是數(shù)組的首地址,可以直接賦給指針

指針與數(shù)組的轉(zhuǎn)換.png

被注釋掉的輸出結(jié)果一樣
數(shù)組是指針常量三圆,所以不能對首地址進(jìn)行自增(++)或自減(--)運(yùn)算狞换,本質(zhì)上是不能對首地址賦值如a=a+1而*(a+1)則是正確的避咆,數(shù)組地址移動方式和指針是相同的,a+i其實是a+i*sizeof(數(shù)組類型),所以對首地址先進(jìn)行移動修噪,然后再顯示新地址內(nèi)的值
指針移動等同數(shù)組.png

所以其實a[i]等價于*(a+i)
2.數(shù)組指針:數(shù)組指針是二維的查库,(只能說)類似于二級指針,要訪問里面的單個元素黄琼,需要使用**
先定義一個數(shù)組指針
int a[2][3]={{1,2,3},{4,5,6}};int (*p)[3]=a;
數(shù)組指針圖解.png

而對p+1則是縱向的移動樊销,移動到4所在地址
數(shù)組指針.png

上圖則是運(yùn)行效果
也可以換一種方式理解為什么需要兩個**:前面提到一維數(shù)組等價于指針,所以二維數(shù)組就相當(dāng)于一維數(shù)組里的元素全是指針脏款,*p訪問到第一個元素還是指針即地址围苫,所以還需要一個*才能訪問到真正的第一個元素

4.動態(tài)分配內(nèi)存

常量區(qū) 常量 const int a=1;程序結(jié)束時釋放
靜態(tài)區(qū) static 直到程序結(jié)束才會被釋放內(nèi)存
靜態(tài)變量只會被初始化一次,生命周期從開始(預(yù)編譯)到程序結(jié)束為止
棧 局部變量 int a=10;作用于代碼塊撤师,出了代碼塊就釋放
堆 自己申請的內(nèi)存(malloc calloc realloc) 必須自己釋放內(nèi)存
為什么需要分配內(nèi)存:
1.存儲的數(shù)據(jù)需要延長生命周期
2.一個指針變量需要存儲數(shù)據(jù)剂府,變量本身只能存地址,不能存數(shù)據(jù)剃盾,需要分配內(nèi)存空間來存儲數(shù)據(jù)腺占,必須為指針變量分配內(nèi)存空間,用malloc,引入stdlib.h
如何分配內(nèi)存
char *name;
name=(char *)malloc(10*sizeof(char));
格式:malloc(需要對應(yīng)數(shù)據(jù)類型空間的數(shù)量*sizeof(對應(yīng)的數(shù)據(jù)類型)),前面需要對其聲明痒谴,(數(shù)據(jù)類型*)
動態(tài)分配內(nèi)存的本質(zhì):malloc函數(shù)在內(nèi)存中申請了一片連續(xù)指定大小的空間單元格衰伯,然后返回那片連續(xù)單元格的首地址
name=(char*)realloc(name,20*sizeofz(char))//重新分配已經(jīng)分配的動態(tài)內(nèi)存
格式:realloc(需要重新分配的指針名,對應(yīng)數(shù)據(jù)類型空間的數(shù)量*sizeof(對應(yīng)的數(shù)據(jù)類型))
為了不浪費空間积蔚,程序結(jié)束之間需要釋放申請的內(nèi)存意鲸,free(name);
以上具體的使用會在實戰(zhàn)篇中體現(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市库倘,隨后出現(xiàn)的幾起案子临扮,更是在濱河造成了極大的恐慌,老刑警劉巖教翩,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杆勇,死亡現(xiàn)場離奇詭異,居然都是意外死亡饱亿,警方通過查閱死者的電腦和手機(jī)蚜退,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來彪笼,“玉大人钻注,你說我怎么就攤上這事∨涿ǎ” “怎么了幅恋?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長泵肄。 經(jīng)常有香客問我捆交,道長淑翼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任品追,我火速辦了婚禮玄括,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘肉瓦。我一直安慰自己遭京,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布泞莉。 她就那樣靜靜地躺著哪雕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪戒财。 梳的紋絲不亂的頭發(fā)上热监,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天捺弦,我揣著相機(jī)與錄音饮寞,去河邊找鬼。 笑死列吼,一個胖子當(dāng)著我的面吹牛幽崩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播寞钥,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼慌申,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了理郑?” 一聲冷哼從身側(cè)響起蹄溉,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎您炉,沒想到半個月后柒爵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡赚爵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年棉胀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冀膝。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡唁奢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出窝剖,到底是詐尸還是另有隱情麻掸,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布赐纱,位于F島的核電站脊奋,受9級特大地震影響采郎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜狂魔,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一蒜埋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧最楷,春花似錦整份、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至犯建,卻和暖如春讲冠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背适瓦。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工竿开, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人玻熙。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓否彩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親嗦随。 傳聞我的和親對象是個殘疾皇子列荔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容