指標和引用的區別

JLU-C++發表於2020-10-27

直接上程式碼,執行即可

#include<iostream>
using namespace std;

int test(int *s){
    *s = *s + 2;
    return *s;
}

int test1(int &s){
    cout<<&s<<endl;//&s = q,變數q的地址
    cout<<s<<endl;//這裡相當於s為q別名
    s = s + 2;
    return s;
}

void test2(int* &r){
    *r = 30;
//    return *r;
}

int main(){
    long double a = 10;

    long double *b = &a;
    long double &c = a;


//    1、指標不需要初始化,引用需要初始化
    long double *e;
//    long double &q = NULL;//error:不能給引用賦值NULL(不能對臨時變數加引用)
//    long double &d;// error :Declaration of reference variable 'd' requires an initializer


//    2、直接輸出指標和引用
//    5、引用訪問一個變數c是直接訪問,而指標是間接訪問(先訪問變數的地址,再訪問值)
    cout<<b<<endl;//指標這裡是輸出的變數b的【地址】:0x70fe30
    cout<<c<<endl;//引用這裡是輸出的變數b的【值】

//    3、通過sizeof來獲取指標和引用的【大小】
    cout<<sizeof(b)<<endl;//指標的大小為8個位元組,因為是64位系統
    cout<<sizeof(c)<<endl;//引用的大小就是其所指向變數a的大小,long double型別16個位元組


//   4、 對指標和引用分別進行加1操作,指標的加1操作就是指向下一個地址空間(指標的值+16,,因為這裡是long double)
    b++;//0x70fe40-0x70fe30=10(這是16進位制的10),也就是16正好是一個long double型別所佔的位元組
    c++;//11,就是變數的值加1
    cout<<b<<endl;
    cout<<c<<endl;

//    6、傳引用就相當於給原有變數起了一個別名s(見test1函式),對s的操作就是對q的操作
//    傳引用,傳遞的【值】是【變數的地址】(&s = q),&是取地址運算子,&s為變數q的地址。
//    傳引用,傳遞的【實質】是變數的地址
//傳遞的值看的是函式裡面的變數比如s
//傳遞的實質是看&s
    cout<<"下面是指標和引用的引數傳遞測試,(為啥傳引用和傳引數,變數的地址都沒有改變)"<<endl;
    int q = 10;
    int &w = q;//w相當於是q的別名
    cout<<w<<endl;
    cout<<&q<<endl;

    cout<<"傳引用之前,q的地址:"<<&q<<endl;
    cout<<test1(q)<<endl;
    cout<<q<<endl;
    cout<<"傳引用之後,q的地址:"<<&q<<endl;

//    傳指標,傳遞的【值】是【指標的地址】(*s = m),
//    傳指標,傳遞的【實質】是
//傳遞的值看的是函式裡面的變數比如s
//傳遞的實質是看*s
//    int *m = &q;
    cout<<"傳指標之前,q的地址:"<<&q<<endl;
    cout<<test(&q)<<endl;
    cout<<"主調函式實參變數的值:"<<q<<endl;
    cout<<"傳指標之後,q的地址:"<<&q<<endl;
//    cout<<test(m)<<endl;


cout<<"下面為多級指標測試"<<endl;
//    https://www.cnblogs.com/johnnyzen/p/7575929.html
//    7、有多級指標但是沒有多級引用
    int value = 10;
    int *pointer1 = &value;
    int **pointer2 = &pointer1;

    cout<<&value<<endl;//0x70fe18為value值的地址
    cout<<&pointer1<<endl;//0x70fe10為pointer1值的地址
    cout<<&pointer2<<endl;//0x70fe08為pointer2值的地址

    cout<<pointer1<<endl;//0x70fe18,pointer1=&value      =value的地址
    cout<<pointer2<<endl;//0x70fe10,pointer2=&pointer1   =pointer1的地址

    cout<<*pointer1<<endl;//*pointer1=value=10
    cout<<*pointer2<<endl;//*pointer2=pointer1=&value=0x70fe18
    cout<<*(&pointer1)<<endl;//解釋同上

    cout<<**pointer2<<endl;//**pointer2=*(*pointer2)=*pointer1=value=10

//    引用變數沒有地址(【系統為引用變數自身分配了地址】,只不過引用變數自身的地址我們連讀的許可權都沒有,
//    所以我們預設引用自身沒有地址,即引用類似常量),所【不能宣告引用的引用,int &&p = 】,【也不能宣告指向引用的指標】

    int i = 10;
    int* p1 = &i;
    int* &r = p1;//相當於int* (&r) = p1
    cout<<p1<<endl;
    cout<<*(&p1)<<endl;//值與上一行一樣,由此可得*(&p1)==p1
    cout<<&p1<<endl;
    cout<<&r<<endl;


    cout<<&i<<endl;
    cout<<p1<<endl;
//    https://blog.csdn.net/boy_of_god/article/details/81022316
    cout<<r<<endl;//見82行,或者上訴部落格的第二張圖
//    上面這一行程式碼解釋:r表示 以引用變數中儲存的內容【p1的地址】為地址的變數【指標p1】的值【i的地址】

    *r = 30;
    cout<<r<<endl;
    cout<<i<<endl;
    cout<<&i<<endl;
    r = (int *)malloc(sizeof(int));
    cout<<r<<endl;
    cout<<&r<<endl;//不變
    cout<<&p1<<endl;//不變
    cout<<p1<<endl;
    cout<<&i<<endl;

    test2(p1);
    cout<<i<<endl;

    return 0;
}

相關文章