c函數編程之指針參數和指向指針的指針參數

c函數編程之指針參數和指向指針的指針參數

我們給出兩個函數如下:

void getMem1(char *p) {
    p = (char*)malloc(sizeof(char) * 100);
}

void getMem2(char **p) {
    *p = (char*)malloc(sizeof(char) * 100);
}

int main() {
    char* str = NULL;
    getMem1(str);
    strcpy(str,"hello");
    //運行上面這一行會報錯,因爲str仍然爲NULL
    getMem2(&str);
    strcpy(str,"hello");
    //運行這一行str可以如願變成“hello”
}

爲什麼會這樣呢?
其實這個問題理解起來有點繞,關鍵是理解變量作函數形參調用的時候都是要分配一個副本,不管是傳值還是傳址。
當我們使用getMem1的時候,str是一個指針,我們創建了臨時變量p,這時p和佔用不同地址空間,只是str的值和p的值一樣。這時候,給p創建一個100char的動態內存空間,然後把這個空間的開始的地址的值存到p裏面去了。這時,p的值變成了指向這100char的地址值。因爲p和str用的是不同的地址空間,str的值沒變還是NULL;
當我們使用getMem2的時候,&str傳遞給函數的是存儲指針str的地址,也就是指向指針str的指針,然後這個值賦給p,此時p和str的內存空間還是不同的。通過*p我們可以獲取到str指針。然後改變 *p的值,此時str的值也跟着改變了,變成了指向一個100char的內存空間的地址。所以後面的操作成功。

說了這麼多,我覺得最重要的是理解指針的概念,指針的值是一個地址,這個地址是一段內存空間的起始地址。指向指針的指針的值也是一個地址,這個地址是存儲另一個指針值的內存空間的起始地址。

總結

在指針做參數傳遞給函數的時候:只能保留指針指向的對象(*P)改變的值。不能保留指針本身(P)所做得修改。在需要修改指針本身的時候,需使用指向指針的指針作爲參數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章