久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2342|回復: 0
收起左側

[C++]筆記二十三:C++引用的本質剖析

[復制鏈接]
ID:244281 發表于 2018-4-3 20:30 | 顯示全部樓層 |閱讀模式
本帖最后由 tyyhmtyyhm 于 2018-4-28 10:02 編輯

第一,引用的意義
1、引用作為其它變量的別名而存,在一些場合可以代替指針;
2、引用相對于指針來說具有更好的可讀性和實用性。(實例可以見之前的交換兩個變量的值程序
第二,引用的本質思考
思考1:引用連接的兩個變量地址相同嗎?
之前我們理解ba的別名,那么變量b有地址嗎?還是跟a地址一樣呢?
我們運行程序:
#include <iostream>
using namespace std;

int main()
{
        //const int a=10;//必須初始化

        int a=10;
        int &b=a; //b很像一個const常量

        cout<<"a="<<a<<endl;//打印a的值
        cout<<"b="<<b<<endl;//打印b的值

//a和b是同一塊內存空間的“門牌號”
        cout<<"&a="<<&a<<endl;//打印a的地址
        cout<<"&b="<<&b<<endl;//打印b的地址

        system("pause");
        return 0;
}
運行結果
a=10
b=10
&a=002EF9FC
&b=002EF9FC
請按任意鍵繼續. . .

發現ab的地址是一樣的,這說明a和b是同一塊內存空間的門牌號。

思考2:引用占不占內存空間呢?
我們知道引用依附于一個變量,那么引用定義的變量占不占內存空間呢?
我們通過結構體來研究一下這個問題:
在結構體中定義兩個引用變量,看下這兩個引用變量占據多大的內存,也就是這個看下這個結構體占據多大的內存。
#include <iostream>
using namespace std;
struct Teacher
{
        char name[64];//64字節
        int age;      //4個字節
        int &a;       //多少個字節?
        int &b;
};
int main()
{
        cout<<"sizeof(Teacher)="<<sizeof(Teacher)<<endl;

        system("pause");
        return 0;
}
運行結果
sizeof(Teacher)=76
請按任意鍵繼續. . .

通過運行我們發現結構體占了76字節,也就是說每個引用占了4個字節內存,這個和指針是一樣的!指針也是占4個字節內存的!
另外,我們知道單獨定義引用時,必須初始化說明引用很像一個const常量。因為定義常量時 const int a = 10;必須初始化,進行賦值,如果不初始化就會報錯。
再加上這部分我們探討發現引用很像一個指針,占據4字節的內存。
先對上面兩部分做個小結:
我們看到引用變量b作為a的別名,二者內存地址相同,但是為什么又分別占據內存呢?援引網上的一句話:由于引用本身就是目標的一個別名,引用本身的地址是一個沒有意義的值,所以在c++中是無法取得引用的內存地址的。取引用的地址就是取目標的地址,c++本身就根本不提供獲取引用內存地址的方法。
第三,引用的本質
1、引用在C++中的內部實現是一個常指針;
Type &name   <----->   Type *const name
2、C++編譯器在編譯過程中使用常指針作為引用的內部實現,因此引用所占用的空間大小與指針相同
3從使用角度,引用會讓人誤認為其只是一個別名,沒有自己的內存空間(目標公用一個內存空間),這是C++為了實用性而做出的細節隱藏就是說C++不想讓人們找到引用自己真實的地址,即使你去取引用變量b的地址,也只是目標變量a的地址。
想下指針變量具有一個地址,指針指向的空間也有一個地址,沒有隱藏,很多指針指向一個對象時,如果一個指針對對象進行了析構,就會使其他指針變成“野指針”,這就很危險!(該點根據自己理解,不當之處請指正!

這兩個函數:
void func(int &a) //函數一
{
        a=5;
}
void func(int *const a) //函數二
{
        *a=5
}
執行函數一的時候,是C++編譯器在背后在背后通過函數的方式進行了編譯。編譯C++看到a是一個引用,就會翻譯成函數二的形式再看下面的程序:
#include <iostream>
using namespace std;

int modifyA(int &a1)
{
        a1=100;
}
int modifyA2(int *a1)
{
        *a1=200;//【*實參的地址】間接修改實參的值
}
int main()
{
        int a=10;

        //指向這個函數調用的時候,我們程序員不需要取a得地址
        modifyA(a);
        cout<<"a="<<a<<endl;

        //如果是指針,需要我們程序員手工的取實參的地址
        modifyA2(&a);
        cout<<"a="<<a<<endl;

        system("pause");
        return 0;
}

當我們執行函數modifyA的時候,是C++編譯器自動的取了a的地址傳遞給了a1。執行modifyA函數調用的時候,我們就不需要再取a的地址了,C++編譯器幫我們取了。如果是執行modifyA2函數,使用指針,就需要傳遞a的地址。
第四引用小結
先來看間接賦值成立的三個條件:
1、定義兩個變量(一個實參一個形參)
2、建立關聯,實參取地址傳給形參
3、*p形參去間接修改實參的值
小結:
1引用在實現上,只不過是把間接賦值成立的三個條件的后兩步合二為一。實參傳給形參引用的時候,只不過是C++編譯器幫我們程序員自動取了一個實參地址,傳給了形參引用(常量指針)。
2、當我們使用引用語法時,我們不去關心編譯器引用是怎么做的當我們分析奇怪的語法現象時,我們才去考慮C++編譯器是怎么做的。

【C++】筆記系列均為原創,轉載請注明轉自微號:依法編程
更多精彩資料,請關注!


回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 99热精品在线观看 | 黄色三级在线播放 | 日韩视频专区 | 国产福利在线 | 免费在线观看一区二区 | 欧美日日 | 日韩久久久久久久久久久 | av在线免费观看网址 | av网站免费观看 | 日韩一区二区三区在线视频 | 亚洲国产精品一区二区www | 成人免费看片 | 网站国产 | 久久久久久高潮国产精品视 | 久久久久久久久久久一区二区 | 国产在线精品一区 | 欧美日韩中文字幕在线 | 91久久夜色精品国产网站 | 亚洲成人精品在线 | 免费视频99 | 国产不卡在线观看 | 国产免费一区二区三区 | 亚洲精品二区 | 亚洲综合色自拍一区 | 国产高清视频在线观看播放 | 精品一区二区三区免费视频 | 国产精品欧美一区二区三区不卡 | 国产精品国产成人国产三级 | 欧美一级电影免费观看 | 97国产精品 | 亚洲一二三区在线观看 | 亚洲第一成人影院 | 久久新视频 | 亚洲精品一二三 | 欧美视频精品 | 亚洲乱码一区二区三区在线观看 | 精品国产乱码一区二区三 | 一区二区在线不卡 | 亚洲精品乱码久久久久久按摩观 | 久久成人一区 | 亚洲欧美激情精品一区二区 |