指針傳遞問題小結

指針值傳遞、地址傳遞和引用傳遞

總結一下指針值傳遞、地址傳遞和引用傳遞 :

指針的值傳遞

//test.c
#include <cstdio>
#include <cstring>
#include <cassert>

void fun(char* p){
    p = (char*)malloc(sizeof(char));
    assert(p!=NULL);
    strcpy(p,"hello");
    //free(p)
}

int main(void){
    char* p = NULL;
    fun(p);
    printf("p=%s\n",p);
}

執行結果中並未輸出字符串hello其實這裏主函數調用fun函數,形參向實參傳遞參數的時候,發生的是拷貝。在fun函數中對局部指針變量p的任何修改都不會影響到主函數中的指針變量p。
值傳遞,形參的修改不會影響到實參

指針的地址傳遞

由於實參是一個一級指針的地址,要傳入這樣的地址給形參,這需要一個對應類型的二級指針來接受一級指針的地址。

//test.c
#include <cstdio>
#include <cstring>
#include <cassert>
void fun(char** p){
    *p = (char*)malloc(sizeof(char)*100);
    assert(*p != NULL);
    strcpy(*p,"hello");
}

int main(void){
    char* p = NULL;
    fun(&p);
    printf("p=%s\n",p);
    free(p); 
    return 0;
}

指針的地址傳遞經常用在沒有頭節點的鏈表中,因爲在創建和銷燬鏈表時,頭指針的值需要被修改。如果用一級指針接收發生的是值傳遞,要修改其值必須用二級指針接收一級指針的地址,在這個地址對應的內存塊進行修改。

指針的引用傳遞

用二級指針操作一級指針的內存往往讓人難以理解,甚至往往還會發生內存泄漏的風險,在C++中,可以通過指針的引用簡化這樣的內存模型,實際上在編譯器內部還是處理爲二級指針,當使用時,解引用爲一級指針,如對無頭結點鏈表的初始化、銷燬等操作,也可以使用一級指針的引用簡化問題的處理

//test.cpp
#include <iostream>
using namespace std;

void fun(char* &p){
    p = new char[100];
    strcpy(p,"hello");
}

int main(){
    char* p=NULL;
    fun(p);
    cout<<"p = "<<p<<endl;
    delete [] p;
    return 0;
}

理解一級指針的引用傳遞,編譯器在內存中開闢了臨時量,用於存儲引用變量的地址,一但使用引用變量就進行解引用。所以在外部看來,似乎就是使用了原變量 。

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