C語言中多級指針的重點分析
一、指針簡介
指針是C語言的靈魂,C語言之所以強大,很大一部分原因在於對指針的靈活運用。我們無論需要對內存的精準分配和釋放,還是對接口api的使用,乃至面向對象中的類和對象的封裝,都涉及到了指針。C語言的指針大致可以分為兩種,一種是作為一個變量,其保存的是一段內存地址,也就是本文要談的多級指針;另一種是作為一種數據類型,像函數指針,用於引出一種類型,主要用於回調函數。
二、指針與基礎數據類型
從內存的角度看,數據類型就是一段固定大小內存塊的別名。
int a=0;
int在32/64位操作系統中都是占用4個字節,這段簡單的代碼相當於告訴編譯器,讓操作系統在棧區分配一塊占4個字節的內存塊,命名為a,並且初始化為0
因此我們可以將這塊內存的地址賦值給一個指針變量。
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語言中多級指針的重點分析