二級指針的作用用處特別大!!!
首先主要在數據結構之中當改變指針的時候就需要通過改變指針的指針的值來改變!
在數據結構中用處很廣.最普遍的比如說鏈表,通過調用函數改變了鏈表中的元素,那么整個鏈表就發生了變化,這種情況下就會用到二級指針,因為鏈表的起始是通過指向頭結點的指針來執行的,所以必須要改變這個指針,怎么樣使一個指針改變?在形參傳遞時,必須傳遞指針的地址,也就是指向指針的指針.
指向指針的指針的作用 :當要修改實參指針的指向的時候,形參必須使用指向指針的指針。
當修改的是實參指針指向的內容時,則形參只需是指針即可
以下是經典程序(載自林銳的從c\c++高質量編程),講解的部分是我個人理解
void GetMemory(char *p,int num) { p=(char*)malloc(sizeof(char)*num); //p是形參指向的地址 } void main() { char *str=NULL; GetMemory(str,100); //str是實參指向的地址,不能通過調用函數來申請內存 strcpy(str,"hello"); }
結構是編譯能通過,卻不能運行,為什么呢?
先說一下指針作為函數參數的意義:當將指針作為參數時,實參向形參傳遞的是地址,在函數執行過程中,既可以對該參數指針進行處理,也可以對該參數指針所指向的數據進行處理,(以上程序段來說就是可以對p或*p進行處理)。由於此時形參和實參都是指向同一個存儲單元,因此當形參指針所指向的數據改變時,實參指針所指向的數據也作相應的改變,因此這時的形參可以作為輸出參數使用。(str和p應同時更改!)
按照上面的說法,這個程序應該沒有問題的啊,實參str和形參p指向同一個存儲單元,給形參分配的內存單元應該也給實參分配了才對啊,問題就是在這里
實參和形參是指向同一個地址,它們只是指向相同,但它們自身的地址不是同時申請的,就是說p在申請內存時,相當於是把p的指向給改了,但是str的指向仍然沒有改!所以盡管str調用了GetMemory,但它仍然是個空指針,所以進行strcpy是就不能運行。
要使程序可以運行,只要小小的改動就行了(用指向指針的指針):
void GetMemory(char **p,int num) { *p=(char*)malloc(sizeof(char)*num); //此時*p就變成了是形參本身的地址 } void main() { char *str=NULL; GetMemory(&str,100); //&str是實參的地址,所以實參和形參之間就可以直接調用 strcpy(str,"hello"); free(str); }
程序就會如你所願,輸出hello了