1. 程式人生 > >引用&指標、傳值&傳引用&傳址的區別

引用&指標、傳值&傳引用&傳址的區別

引用

概念(貼標籤式)

引用不是新定義一個變數,而是給已存在變數取了一個別名,編譯器不會為引用變數開闢記憶體空間,它和它引用的變數共用同一塊記憶體空間
型別& 引用變數名(物件名) = 引用實體;

這裡寫圖片描述

使用場景

1.作為函式形參
2.作為函式返回值

注意事項

a. 引用在定義時必須初始化
b. 一個變數可以有多個引用
c. 引用一旦引用一個實體,再不能引用其他實體
d.不能返回棧空間上的引用

//下列程式碼執行結果是?
int& Add(int a, int b){
    int
c = a + b; return c; } int main(){ int a = 10; int b = 20; int& sum = Add(a,b); cout << sum << endl; cout << sum << endl; return 0; }
//陣列的引用
int a[10] = {0};
int (&ra)[10] = a;

引用與指標

相同點:
底層的實現方式相同,都是按照指標的方式來實現的

不同點:
1.引用在定義時必須初始化,指標沒有要求
2.一旦一個引用被初始化為指向一個物件,就不能再指向其他物件,而指標可以在任何時候指向任何一個同類型物件
3.沒有NULL引用,但有NULL指標
4.在sizeof中含義不同:引用結果為引用型別的大小,但指標始終是地址*空間所佔位元組個數
5.引用自加改變變數的內容,指標自加改變了指標指向


6.有多級指標,但是沒有多級引用
7.指標需要手動定址,引用通過編譯器實現定址
8.引用比指標使用起來相對更安全

傳值與傳址區別:

傳值

傳值方式,在函式呼叫過程中會生成一份臨時變數用形參代替,最終把實參的值傳遞給新分配的臨時變數即形參

優點:實參不會被汙染改變

缺點:改變不了外部實參,當實引數量過大時,效率低,生成大量臨時變數

傳址:

優點:對引數的改變可以體現在外部實參上,當實引數據量過大時,傳址效率高

缺點:不安全,容易被改變

傳引用

這裡寫圖片描述

傳址、傳值、傳引用的效率

傳引用 與傳址差不多,速率遠大於傳值

//通過下列程式碼 改變傳參方式 可觀測三種傳參方式的效率
typedef struct Arr{
    int arr[10000];
}A;

void fun(A a)
{
}

void Test(){
    A a;
    for (int i = 0; i < 10000000; ++i){
        fun(a);
    }
}

int main(){
    size_t BeginTime = GetTickCount();
    Test();
    size_t EndTime = GetTickCount();

    cout << EndTime - BeginTime << endl;

    return 0;
}

下列程式碼執行之後結果?

void Swap(int& a, int& b){
    int tmp = a;
    a = b; //崩
    b = tmp;
}
int main(){
    int a = 10;
    int *p = NULL;

    Swap(a, *p);

    return 0;
}

可以編譯連結,執行後,程式崩潰,b所引用的空間為空