1. 程式人生 > >C語言中多級指針的重點分析

C語言中多級指針的重點分析

深拷貝 一個 調用方法 簡介 pointer resp har 對象 字節

一、指針簡介

指針是C語言的靈魂,C語言之所以強大,很大一部分原因在於對指針的靈活運用。我們無論需要對內存的精準分配和釋放,還是對接口api的使用,乃至面向對象中的類和對象的封裝,都涉及到了指針。C語言的指針大致可以分為兩種,一種是作為一個變量,其保存的是一段內存地址,也就是本文要談的多級指針;另一種是作為一種數據類型,像函數指針,用於引出一種類型,主要用於回調函數。

二、指針與基礎數據類型

  從內存的角度看,數據類型就是一段固定大小內存塊的別名。

int a=0;

int在32/64位操作系統中都是占用4個字節,這段簡單的代碼相當於告訴編譯器,讓操作系統在棧區分配一塊占4個字節的內存塊,命名為a,並且初始化為0

,a為變量名。
因此我們可以將這塊內存的地址賦值給一個指針變量。

int* p=&a;

即p保存了a的地址,通過*p可以間接的改變a的值。而這樣修改最大的好處是在於在函數調用中,或者說在不同模塊中能夠修改a的值。下面講講在開發中遇到的情形

char* p=NULL;
char buf[32]=" key1=  value";

假設上述代碼是在主調函數中定義的,那麽指針p在向NULL,意味著我們希望能在被調用分配內存,然後使p指向所分配的內存空間,那麽此時就需要使用二級指針來存放p的地址了,假設我們需要設計一個去除字符串中的空格的函數,那麽其接口如下

int ReSpace(char
* p1,int len,char** p2,int* len2) {.....}

調用方法:

char buf[32] = "key1=  value";
char* p = NULL;
int len1 = strlen(buf);
int len2 = 0;
ReSpace(buf,len1,&p,&len2)

即函數將去除空格的字符串通過p傳出來了。同時二級指針也可以記錄字符數組,或者二位數組的內存地址。因此也可以推出三級指針甚至是多級指針的用法了,即用來修改二級指針的值。

三、指針與結構數據類型

  1、結構體類型:

有以下一段代碼

typedef struct
_SCK_HANDLE { char version[64]; char ip[128]; int port; unsigned char *p; int plen; }SCK_HANDLE; void main() { SCK_HANDLE *hdl = NULL; hdl = (SCK_HANDLE *)malloc(sizeof(SCK_HANDLE)); }



即聲明了一個結構體類型的指針,並且給它分配了內存空間,那麽就可以將hdl指針作為一個參數傳遞給其他模塊來改變這塊內存中的值。

  2、數組指針

  初學C語言往往很難理解數組指針,也很容易和指針數組相混淆,事實上,如果只要明白數組指針就是一個行指針,指向的是一個數組,保存的是一個數組的地址。它的步長是數組的列數

     int c[5];
     int (*pointer)[5] = &c;

     int buf[10][30];
     int (*p)[30]=buf;   //    指向二維數組的首行 

四、使用指針時常見的錯誤

 1、用指針修改內存中的值時,應該確保所指的值能夠被修改。如:    

char* p="abcdefg";
p[0]=w;   //錯誤,指向的是常量區的字符常量

  2、註意深拷貝和淺拷貝,即應該明確用指針分配了多少內存空間,以免出現重復釋放內存的問題。

3、指針的步長問題

    指針步長和其存放的數據類型有關,每移動一步,編譯器都會乘以其存放數據類型的長度,相當於移動到下一個數據。

4、sizeof 指針 求的是指針變量所占的內存,sizeof 數組名 求的 是數組所占的內存。

5、避免出現“野指針”,即釋放指針所指的內存空間後,將指針置NULL。

總結

  指針是C語言中很細致的一個語法,再怎麽說也說不完指針的所有應該場景。但是我們只要抓住它的根本,即從內存的角度去理解,分析,那麽它就變得很好理解。我們在平時的學習中,多去應用它,學習指針的思想,站在內存的角度去思考,那麽整個C語言的學習都會有很大的提升。

C語言中多級指針的重點分析