瘋狂的c指針

前言

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

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


1.1 指針和內(nèi)存

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

  • 靜態(tài)/全局內(nèi)存
    靜態(tài)聲明的變量分配在這里,全局變量也使用這部分內(nèi)存。這些變量在程序開始運(yùn)行時分配,知道程序終止才消失。所有函數(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個變量(通常一個實(shí)參,一個形參)
        b) 建立關(guān)系,實(shí)參取地址賦給形參指針
        c) *p形參去間接修改實(shí)參的值
4)引申:函數(shù)調(diào)用時,用n指針(形參)改變n-1指針(實(shí)參)的值。
   //改變0級指針(int iNum = 1)的值有2種方式
   //改變1級指針(eg char *p = 0x1111 )的值,有2種方式
   //改變2級指針的(eg char **pp1 = 0x1111 )的值,有2種方式
   //函數(shù)調(diào)用時,形參傳給實(shí)參,用實(shí)參取地址,傳給形參,在被調(diào)用函數(shù)里面用*p,來改變實(shí)參,把運(yùn)算結(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)系以及指針使用過程中需要注意事項(xiàng)和總結(jié),牢記這些指針的使用就沒有太大的問題了。后期將逐一介紹案例,加強(qiáng)印象。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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