中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++引用的本質與意義是什么

發布時間:2022-04-21 17:04:45 來源:億速云 閱讀:205 作者:iii 欄目:開發技術

本篇內容介紹了“C++引用的本質與意義是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

一、引用的意義

  • 引用作為變量別名而存在,因此在一些場合可以代替指針

  • 引用相對于指針來說具有更好的可讀性和實用性

C++引用的本質與意義是什么

下面通過代碼來進行說明,在C語言中,可以這么寫:

#include <stdio.h>
void swap(int* a, int* b)
{
	int t = *a;
	*a = *b;
	*b = t;
}
int main()
{
	int a = 1;
	int b = 2;
	swap(&a, &b);
	printf("a = %d, b = %d\n", a, b);
	return 0;
}

下面為輸出結果,可以看到a,b被交換。

C++引用的本質與意義是什么

若采用C++用的引用,則采用下面的代碼:

#include <stdio.h>
void swap(int& a, int& b)
{
	int t = a;
	a = b;
	b = t;
}
int main()
{
	int a = 1;
	int b = 2;
	swap(a, b);
	printf("a = %d, b = %d\n", a, b);
	return 0;
}

下面為輸出結果,需要注意的是,引用作為函數的形參時,不需要進行初始化,初始化發生在函數調用的時候(形參一旦被初始化后,就代表兩個具體的外部變量)。

C++引用的本質與意義是什么

二、特殊的引用

const 引用

  • 在C++中可以聲明const 引用

  • const Type& name = var ;

  • const 引用讓變量擁有只讀屬性

  • 當使用常量對const引用進行初始化時,C++編譯器會為常量值分配空間,并將引用名作為這段空間的別名

C++引用的本質與意義是什么

所以上面那段代碼,b = 5 是不正確的,因為 b 已經是只讀變量了,但是依舊可以通過指針改變這個只讀變量的值。

結論:使用常量對const 引用初始化后將生成一個只讀變量

下面看一段代碼,加深理解:

#include <stdio.h>
void Example()
{
    printf("Example:\n");
    int a = 4;
    const int& b = a;
    int* p = (int*)&b;
    //b = 5;
    *p = 5;
    printf("a = %d\n", a);
    printf("b = %d\n", b);
}
void Demo()
{
    printf("Demo:\n");
    const int& c = 1;
    int* p = (int*)&c;
    //c = 5;
    *p = 5;
    printf("c = %d\n", c);
}
int main(int argc, char *argv[])
{
    Example();
    printf("\n");
    Demo();
    return 0;
}

下面為輸出結果:

C++引用的本質與意義是什么

如果把那兩行(b = 5,c = 5)取消注釋,則就會輸出下面結果,編譯器會報 b 和 c 都是只讀變量的錯誤。

C++引用的本質與意義是什么

三、引用是否占用存儲空間

下面看一段代碼:

#include <stdio.h>
struct TRef
{
    char& r;
};
int main(int argc, char *argv[])
{ 
    char c = 'c';
    char& rc = c;
    TRef ref = { c };
    printf("sizeof(char&) = %d\n", sizeof(char&));	//char類型占用一個字節 1
    printf("sizeof(rc) = %d\n", sizeof(rc));	//sizeof(c) => 1
    printf("sizeof(TRef) = %d\n", sizeof(TRef));	//?
    printf("sizeof(ref.r) = %d\n", sizeof(ref.r));	//sizeof(c) => 1
    return 0;
}

下面為輸出結果,可以看到sizeof(TRef)占用的內存空間為4,我們知道指針占用的內存空間為4,那么指針和引用到底有什么關系呢?第4節來分析。

C++引用的本質與意義是什么

四、引用的本質

引用在C++中的內部實現是一個指針常量

C++引用的本質與意義是什么

注意:

  • C++編譯器在編譯過程中用指針常量作為引用的內部實現,因此引用所占用的空間大小與指針相同。

  • 從使用的角度,引用只是一個別名,C++為了實用性而隱藏了引用的存儲空間這一細節。

通過下面的代碼,也可以很好的理解引用所占的字節數:

#include <stdio.h>
struct TRef
{
    char* before;
    char& ref;
    char* after;
};
int main(int argc, char* argv[])
{
    char a = 'a';
    char& b = a;
    char c = 'c';
    TRef r = {&a, b, &c};
    printf("sizeof(r) = %d\n", sizeof(r));
    printf("sizeof(r.before) = %d\n", sizeof(r.before));
    printf("sizeof(r.after) = %d\n", sizeof(r.after));
    printf("&r.before = %p\n", &r.before);
    printf("&r.after = %p\n", &r.after);
    return 0;
}

下面為輸出結果,可以看到結構體占用12個字節,before 和 after 指針各占用4個字節,所以 ref 引用當然也占用4個字節,通過 after 的起始內存地址減上 before 的起始內存地址得8,而 before 指針占用4個字節,從這個層面也能知道 ref 引用占用4個字節。

C++引用的本質與意義是什么

為了深入理解引用的本質,可以在 Visual Studio 2012 中進行反匯編,如下圖,現在return 0那里打個斷點,然后點擊本地 Windows 調試器,開始執行代碼。

C++引用的本質與意義是什么

執行完代碼后,鼠標右擊空白區域,選擇轉到反匯編。

C++引用的本質與意義是什么

下面看一下反匯編的部分代碼,主要看引用那部分的匯編代碼,lea eax,[a] 表示取a的地址,存到 eax 寄存器中,mov dword ptr [b],eax表示把a 的地址保存到 b 所對應的4個內存空間里面去。可以這么說,引用的內部實現就是指針,所以引用占用內存空間,且占用內存空間大小和指針一樣。

C++引用的本質與意義是什么

五、引用的注意事項

C++中的引用旨在大多數的情況下代替指針

  • 功能性:可以滿足多數需要使用指針的場合

  • 安全性∶可以避開由于指針操作不當而帶來的內存錯誤

  • 操作性∶簡單易用,又不失功能強大

下面通過一個函數返回引用,介紹一下引用的注意事項。

#include <stdio.h>
int& demo()    //從內部實現來看,想返回一個指針 int* const
{
    int d = 0;
    printf("demo: d = %d\n", d);
    return d; //本質上,相當于 return &d
}
int& func()
{
    static int s = 0;
    printf("func: s = %d\n", s);
    return s;    //本質上,相當于 return &s
}
int main(int argc, char* argv[])
{
    int& rd = demo();
    int& rs = func();
    printf("\n");
    printf("main: rd = %d\n", rd);
    printf("main: rs = %d\n", rs);
    printf("\n");
    rd = 10;
    rs = 11;
    demo();
    func();
    printf("\n");
    printf("main: rd = %d\n", rd);
    printf("main: rs = %d\n", rs);
    printf("\n");
    return 0;
}

下面為輸出結果,可以看到編譯的時候開始發出警告說不能返回局部變量,如果繼續運行,可以看到 rd = 9658356,rd 為 d 的別名,按理說應該輸出 0 的,為什么輸出9658356 呢?這個因為 rd 所代表的的變量在 demo 函數調用返回的時候被摧毀了,其所代表的是一個不存在的變量,所以 rd 沒有意義了。

C++引用的本質與意義是什么

引用中必須遵守的規則:不要返回局部變量的引用。 如果局部變量是靜態的,則可以。因為靜態局部變量的存儲區是全局的存儲區,所以它的空間不會因為函數的返回而被摧毀。

“C++引用的本質與意義是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

c++
AI

林甸县| 梁山县| 宁德市| 迭部县| 柳河县| 金华市| 祁门县| 密山市| 西乌珠穆沁旗| 华坪县| 深水埗区| 五家渠市| 长垣县| 嵊州市| 西安市| 望奎县| 丰宁| 启东市| 永仁县| 永嘉县| 札达县| 卢龙县| 黎城县| 邵阳市| 永顺县| 边坝县| 阜康市| 离岛区| 客服| 彰化市| 通城县| 焦作市| 响水县| 滁州市| 莫力| 承德市| 克拉玛依市| 聂拉木县| 玉林市| 逊克县| 旬阳县|