瘋狂的c指針

前言

眾所周知冕香,C程序員新手和老手的一大差別就在于是否對指針有深刻理解祠肥,能否高效利用指針纸镊。
可以說學(xué)好c指針對于以后的開發(fā)工作至關(guān)重要鸵闪,所以在這里整理出了一系列關(guān)于指針的文章檐晕,
供大家一起學(xué)習(xí)進步。

本期簡要介紹指針蚌讼、指針操作符以及指針如何與內(nèi)存相互作用辟灰。


1.1 指針和內(nèi)存

C程序在編譯后,會以以下三種形式使用內(nèi)存啦逆。

  • 靜態(tài)/全局內(nèi)存
    靜態(tài)聲明的變量分配在這里伞矩,全局變量也使用這部分內(nèi)存。這些變量在程序開始運行時分配夏志,知道程序終止才消失乃坤。所有函數(shù)都能訪問全局變量,靜態(tài)變量的作用域則局限在定義他們的函數(shù)內(nèi)部沟蔑。
  • 自動內(nèi)存
    這些變量在函數(shù)內(nèi)部聲明湿诊,并且在函數(shù)被調(diào)用時才創(chuàng)建。它們的作用域局限在函數(shù)內(nèi)部瘦材,而且生命周期局限在函數(shù)的執(zhí)行時間內(nèi)厅须。
  • 動態(tài)內(nèi)存
    內(nèi)存分配在堆上,可以根據(jù)需要釋放食棕,而且直到釋放才消失朗和。指針引用分配的內(nèi)存,作用域局限于引用內(nèi)存的指針簿晓。

理解這些內(nèi)存類型可以更好地理解指針眶拉。大部分指針用來操作內(nèi)存中的數(shù)據(jù),因此理解內(nèi)存的分布和組織方式有助于我們弄清楚指針如何操作內(nèi)存憔儿。

指針變量包含內(nèi)存中別的變量忆植、對象或函數(shù)的地址。對象就是內(nèi)存分配函數(shù)(比如malloc)分配的內(nèi)存谒臼。指針通常根據(jù)所指的數(shù)據(jù)類型來聲明朝刊。對象可以是任何C數(shù)據(jù)類型,如整數(shù)蜈缤、字符拾氓、字符串或結(jié)構(gòu)體。然而劫樟,指針本身并沒有包含所引用數(shù)據(jù)的類型信息痪枫,指針只包含地址织堂。

1.2 指針幾大使用鐵律

鐵律1:指針是一種數(shù)據(jù)類型

1) 指針是一種數(shù)據(jù)類型也是一個變量,占有內(nèi)存空間,用來保存內(nèi)存地址。
    a)   說它是一種數(shù)據(jù)類型奶陈,那他究竟是什么類型呢
         指針的數(shù)據(jù)類型是指它所指向內(nèi)存空間的數(shù)據(jù)類型
    // 測試指針變量占有內(nèi)存空間大小:注意32/64位之分
    int a = 10;
    int *p = &a;
    size_t size = sizeof(p);
    printf("%zu\n", size);// 8
    printf("%p\n", p);// 0x7fff5fbff7c4
2) *p操作內(nèi)存
    在指針聲明時易阳,*號表示所聲明的變量為指針
    在指針使用時,*號表示操作指針?biāo)赶虻膬?nèi)存空間中的值
    *p相當(dāng)于通過地址(p變量的值)找到一塊內(nèi)存吃粒;然后操作內(nèi)存
    *p放在等號的左邊賦值(給內(nèi)存賦值)
    *p放在等號的右邊取值(從內(nèi)存獲取值)
3) 指針變量和它指向的內(nèi)存塊是兩個不同的概念
    含義1 給p賦值p = 0x1111; 只會改變指針變量值潦俺,不會改變所指的內(nèi)容;p += 1;p++
    含義2 給*p賦值*p = 'a'; 不會改變指針變量的值徐勃,只會改變所指的內(nèi)存塊的值
    含義3 =左邊*p 表示 給內(nèi)存賦值事示, =右邊*p 表示取值 含義不同切結(jié)!
    含義4 =左邊char *p
    含義5 保證所指的內(nèi)存塊能修改
4) 指針是一種數(shù)據(jù)類型僻肖,是指它指向的內(nèi)存空間的數(shù)據(jù)類型
    含義1:指針步長(p++)肖爵,根據(jù)所致內(nèi)存空間的數(shù)據(jù)類型來確定
    p++=?(unsigned char )p+sizeof(a);
    結(jié)論:指針的步長,根據(jù)所指內(nèi)存空間類型來定臀脏。

注意: 不斷的給指針變量賦值劝堪,就是不斷的改變指針變量(和所指向內(nèi)存空間沒有任何關(guān)系)。

鐵律2: 間接賦值(*p)是指針存在的最大意義

1) 兩碼事:指針變量和它指向的內(nèi)存塊變量
2) 條件反射:指針指向某個變量揉稚,就是把某個變量地址傳給指針
3) *p間接賦值成立條件:3個條件
        a) 2個變量(通常一個實參秒啦,一個形參)
        b) 建立關(guān)系,實參取地址賦給形參指針
        c) *p形參去間接修改實參的值
4)引申:函數(shù)調(diào)用時,用n指針(形參)改變n-1指針(實參)的值搀玖。
   //改變0級指針(int iNum = 1)的值有2種方式
   //改變1級指針(eg char *p = 0x1111 )的值余境,有2種方式
   //改變2級指針的(eg char **pp1 = 0x1111 )的值,有2種方式
   //函數(shù)調(diào)用時灌诅,形參傳給實參芳来,用實參取地址,傳給形參猜拾,在被調(diào)用函數(shù)里面用*p绣张,來改變實參,把運算結(jié)果傳出來关带。
   //指針作為函數(shù)參數(shù)的精髓。

鐵律3: 間接賦值(*p)是指針存在的最大意義

 1) 主調(diào)函數(shù) 被調(diào)函數(shù)
      a) 主調(diào)函數(shù)可把堆區(qū)沼撕、棧區(qū)宋雏、全局?jǐn)?shù)據(jù)內(nèi)存地址傳給被調(diào)用函數(shù)
      b) 被調(diào)用函數(shù)只能返回堆區(qū)、全局?jǐn)?shù)據(jù)
2) 內(nèi)存分配方式
      a) 指針做函數(shù)參數(shù)务豺,是有輸入和輸出特性的磨总。

鐵律4:應(yīng)用指針必須和函數(shù)調(diào)用相結(jié)合(指針做函數(shù)參數(shù))

鐵律5:一級指針典型用法(指針做函數(shù)參數(shù))

 // 一級指針做輸入
 int showbuf(char *p)
 int showArray(int *array, int iNum)
 // 一級指針做輸出
 int geLen(char *pFileName, int *pfileLen);
 理解
 主調(diào)函數(shù)還是被調(diào)用函數(shù)分配內(nèi)存
 被調(diào)用函數(shù)是在heap/stack上分配內(nèi)存

鐵律6:二級指針典型用法(指針做函數(shù)參數(shù))

 // 二級指針做輸入
 int main(int arc ,char *arg[]); 字符串?dāng)?shù)組
 int shouMatrix(int [3][4], int iLine);
 // 二級指針做輸出
 int Demo64_GetTeacher(Teacher **ppTeacher);
 int Demo65_GetTeacher_Free(Teacher **ppTeacher);
 int getData(char **data, int *dataLen);
 Int getData_Free(void *data);
 Int getData_Free2(void **data); //避免野指針
 理解
 主調(diào)函數(shù)還是被調(diào)用函數(shù)分配內(nèi)存
 被調(diào)用函數(shù)是在heap/stack上分配內(nèi)存

1.3 summary

以上就是現(xiàn)階段指針與內(nèi)存之間的聯(lián)系以及指針使用過程中需要注意事項和總結(jié),牢記這些指針的使用就沒有太大的問題了笼沥。后期將逐一介紹案例蚪燕,加強印象娶牌。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市馆纳,隨后出現(xiàn)的幾起案子诗良,更是在濱河造成了極大的恐慌,老刑警劉巖鲁驶,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鉴裹,死亡現(xiàn)場離奇詭異,居然都是意外死亡钥弯,警方通過查閱死者的電腦和手機径荔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來脆霎,“玉大人总处,你說我怎么就攤上這事【χ耄” “怎么了鹦马?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長玖院。 經(jīng)常有香客問我菠红,道長,這世上最難降的妖魔是什么难菌? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任试溯,我火速辦了婚禮,結(jié)果婚禮上郊酒,老公的妹妹穿的比我還像新娘遇绞。我一直安慰自己,他們只是感情好燎窘,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布摹闽。 她就那樣靜靜地躺著,像睡著了一般褐健。 火紅的嫁衣襯著肌膚如雪付鹿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天蚜迅,我揣著相機與錄音舵匾,去河邊找鬼。 笑死谁不,一個胖子當(dāng)著我的面吹牛坐梯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播刹帕,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼吵血,長吁一口氣:“原來是場噩夢啊……” “哼谎替!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蹋辅,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤钱贯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后晕翠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喷舀,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年淋肾,在試婚紗的時候發(fā)現(xiàn)自己被綠了硫麻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡樊卓,死狀恐怖拿愧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情碌尔,我是刑警寧澤浇辜,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站唾戚,受9級特大地震影響柳洋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜叹坦,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一熊镣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧募书,春花似錦绪囱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至篮赢,卻和暖如春齿椅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背启泣。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工媒咳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人种远。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像顽耳,于是被迫代替她去往敵國和親坠敷。 傳聞我的和親對象是個殘疾皇子妙同,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

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

  • 指針是C語言中廣泛使用的一種數(shù)據(jù)類型。 運用指針編程是C語言最主要的風(fēng)格之一膝迎。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu)粥帚; ...
    朱森閱讀 3,424評論 3 44
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,506評論 1 51
  • __block和__weak修飾符的區(qū)別其實是挺明顯的:1.__block不管是ARC還是MRC模式下都可以使用,...
    LZM輪回閱讀 3,284評論 0 6
  • 1. C++基礎(chǔ)知識點 1.1 有符號類型和無符號類型 當(dāng)我們賦給無符號類型一個超出它表示范圍的值時限次,結(jié)果是初始值...
    Mr希靈閱讀 17,937評論 3 82
  • 愛學(xué)習(xí)的胖大媽最近看了好多書卖漫,然而每次看了忘费尽,忘了看,看了又忘羊始,不知該如何是好旱幼。 胖大爺這次奇跡般地給她帶來了一本...
    胖燈閱讀 221評論 3 5