溫馨提示×

溫馨提示×

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

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

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

發(fā)布時間:2022-05-16 14:22:35 來源:億速云 閱讀:193 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用”,在日常操作中,相信很多人在C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

1.內(nèi)斂函數(shù)

1.1問題引入

我們在使用C語言中我們都學過函數(shù),我們知道函數(shù)在調(diào)用的過程中需要開辟棧幀。如果我們需要頻繁的調(diào)用一個函數(shù),假設(shè)我們調(diào)用10次Add()函數(shù),那我們就需要建立10次棧幀。我們都知道在棧幀中要做很多事情,例如保存寄存器,壓參數(shù),壓返回值等等,這個過程是很麻煩的。那在C語言中,我們可以通過宏來解決這個問題。在C++中,我們便引入了內(nèi)斂函數(shù)(inline)。

1.2內(nèi)聯(lián)函數(shù)的概念

以inline修飾的函數(shù)叫做內(nèi)聯(lián)函數(shù),編譯時C++編譯器會在調(diào)用內(nèi)聯(lián)函數(shù)的地方展開,沒有函數(shù)壓棧的開銷,內(nèi)聯(lián)函數(shù)提升程序運行的效率。

我們這里依然使用Add()函數(shù)舉例。這段代碼是我們常寫的Add()函數(shù)。假設(shè)我們多次調(diào)用Add函數(shù),在C語言中,我們可以使用宏替換。在C++我們可以在函數(shù)前加上inline

int Add(int x, int y)
{
	int z = x + y;
	return z;
}

C語言中用宏來代替Add函數(shù):

#define Add(x,y) ((x)+(y))

C++中在函數(shù)前加上inline使之成為內(nèi)聯(lián)函數(shù)

inline int Add(int x, int y)
{
	int z = x + y;
	return z;
}

那C語言已經(jīng)有了宏替換,為什么C++還要出現(xiàn)內(nèi)聯(lián)函數(shù)呢?

主要是有兩個原因:

1.宏晦澀難懂不好控制,特別容易寫錯.語法機制設(shè)計不好。

2.宏不支持調(diào)試,但是內(nèi)斂在debug下支持調(diào)試(在debug下不會展開,在release下才會展開),這樣我們對代碼的理解和掌握將大大提高。

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

如果在Add函數(shù)前增加 inline 關(guān)鍵字將其改成內(nèi)聯(lián)函數(shù),在編譯期間編譯器會用函數(shù)體替換函數(shù)的調(diào)用。 查看方式:

1. 在 release 模式下,查看編譯器生成的匯編代碼中是否存在 call Add

2. 在 debug 模式下,需要對編譯器進行設(shè)置,否則不會展開 ( 因為 debug 模式下,編譯器默認不會對代碼進 行優(yōu)化,以下給出 vs2019 的設(shè)置方式 )

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

1.3內(nèi)斂函數(shù)的特性

1. inline 是一種 以空間換時間 的做法,省去調(diào)用函數(shù)額開銷。所以 代碼很長 或者有 循環(huán) / 遞歸 的函數(shù)不適宜使用作為內(nèi)聯(lián)函數(shù)。

2. inline 對于編譯器而言只是一個建議 ,編譯器會自動優(yōu)化,如果定義為 inline 的函數(shù)體內(nèi)有循環(huán) / 遞歸等等,編譯器優(yōu)化時會忽略掉內(nèi)聯(lián)。

3. inline 不建議聲明和定義分離,分離會導致鏈接錯誤。因為 inline 被展開,就沒有函數(shù)地址了,鏈接就會找不到

  • inline是一種以空間換時間的做法,省去調(diào)用函數(shù)額開銷(建立棧幀).所以代碼很長或者遞歸的函數(shù)不適宜用內(nèi)聯(lián)函數(shù).

這里代碼多長算長呢? 一般是10行左右,具體取決于編譯器。

  • inline對于編譯器而言只是一個建議,編譯器會自動優(yōu)化,如果定義為inline的函數(shù)體內(nèi)有循環(huán)/遞歸等等,編譯器優(yōu)化時會忽略掉內(nèi)聯(lián)。

這里可以舉個例子,假設(shè)我們有一個代碼需要10行,但是我們需要調(diào)用1000次。如果inline替換的話,我們要有1000*10條指令,如果不替換則有1000+10條指令。因此最終是否替換,取決于編譯器。

inline int Add(int x, int y)
{
	int z = x + y;
	z += x * y;
	z += x * y;
	z += x * y;
	z += x * y;
	z += x * y;
	z += x * y;
	z += x * y;
	z += x * y;
	z += x * y;
	z += x * y;
	z += x * y;
	return z;
}

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

我們發(fā)現(xiàn),雖然Add函數(shù)前加了inline,但是最終卻沒有展開。

  • inline不建議聲明和定義分離,分離會導致鏈接錯誤。因為inline被展開,就沒有函數(shù)地址了,鏈接就會找不到

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

我們在f.cpp中調(diào)用一下:發(fā)現(xiàn)報錯了

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

在這里他就會發(fā)生鏈接錯誤:

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

這是因為test.h中替換到test.cpp中發(fā)現(xiàn)是內(nèi)聯(lián)函數(shù),內(nèi)聯(lián)函數(shù)不需要生成地址,因為內(nèi)聯(lián)函數(shù)調(diào)用的地方都展開了,因此不會存在在符號表中。外部調(diào)用時就找不到。因此不要將聲明和定義分開。

2.auto關(guān)鍵字

2.1 auto簡介

在早期 C/C++ 中 auto 的含義是:使用 auto 修飾的變量,是具有自動存儲器的局部變量。C++11中,標準委員會賦予了auto 全新的含義即: auto 不再是一個存儲類型指示符,而是作為一個新的類型 指示符來指示編譯器, auto 聲明的變量必須由編譯器在編譯時期推導而得

auto在C語言中我們是接觸過的:最寬宏大量的關(guān)鍵字,由于局部變量默認都是auto修飾的,因此auto可以省略,這就導致auto常常被人忽略。那么在C++11中,auto進行了升級,有了新的功能--自動推導。(注意:auto新功能只是在C++11之后才有此功能)

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

那么auto是怎么自動推導呢?

我們可以使用typeid,來打印一個變量的類型。

int main()
{
    const int  a = 10;
	auto b = &a;
	auto c = 'a';
	cout << typeid(b).name() << endl;//typeid可以打印一個變量的類型
	cout << typeid(a).name() << endl;//typeid可以打印一個變量的類型
	cout << typeid(c).name() << endl;//typeid可以打印一個變量的類型
	return 0;
}

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

我們發(fā)現(xiàn)auto的自動推導還是很智能的。

auto意義之一:類型很長時,懶得寫,可以讓他自動推導

注意:

使用 auto 定義變量時必須對其進行初始化,在編譯階段編譯器需要根據(jù)初始化表達式來推導 auto 的實際類 型 。因此 auto 并非是一種 “ 類型 ” 的聲明,而是一個類型聲明時的 “ 占位符 ” ,編譯器在編譯期會將 auto 替換為 變量實際的類型 。

2.2 auto的使用細則

1. auto與指針和引用結(jié)合起來使用auto聲明指針類型時,用auto和auto*沒有任何區(qū)別,但用auto聲明引用類型時則必須加&.

int main()
{
	int x = 10;
	auto a = &x;
	auto& c = x;
	cout << typeid(x).name() << endl;//typeid可以打印一個變量的類型
	cout << typeid(a).name() << endl;//typeid可以打印一個變量的類型
	cout << typeid(c).name() << endl;//typeid可以打印一個變量的類型
	return 0;
}

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

2. 在同一行定義多個變量當在同一行聲明多個變量時,這些變量必須是相同的類型,否則編譯器將會報錯,因為編譯器實際只對第一個類型進行推導,然后用推導出來的類型定義其他變量。

	auto a = 1, b = 2;
	auto c = 3, d = 4.0;//c和d類型不同,auto推導會沖突的

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

2.3 auto不能推導的場景

1. auto不能作為函數(shù)的參數(shù)

// 此處代碼編譯失敗,auto不能作為形參類型,因為編譯器無法對a的實際類型進行推導
void TestAuto(auto a)
{}

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

2. auto不能直接用來聲明數(shù)組

void TestAuto()
{
	int a[] = { 1,2,3 };
	auto b[] = { 4,5,6 };
}

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

2.4 auto與新式for循環(huán)使用

在平常我們打印一個array數(shù)組,我們需要依次打印遍歷。如下代碼所示:

int main()
{
	int array[] = { 1,2,3,4,5 };
	for (int i = 0; i < sizeof(array) / sizeof(int); ++i)
		array[i] *= 2;
	for (int i = 0; i < sizeof(array) / sizeof(int); ++i)
		cout << array[i] << " ";
	cout << endl;
	return 0;
}

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

我們也可以使用auto結(jié)合范圍for循環(huán)打印這個數(shù)組:

	for (auto e : array)
		cout << e << " ";
	cout << endl;

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

在這里我們使用到了一個新的for循環(huán),范圍for。它會依次自動取array中的數(shù)據(jù),賦值給e,并且會自動判斷結(jié)束,因此我們使用auto可以自動識別數(shù)組元素的類型。

注意:e只是array的拷貝,改變e不會改變array數(shù)組的內(nèi)容。如果我們想改變array的內(nèi)容,只需要加個引用即可,意思是讓e成為array的別名,代碼如下:

	//加個引用就可以訪問到array
	for (auto& e : array)
	{
		e /= 2;
	}
	for (auto e : array)
		cout << e << " ";

C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用

到此,關(guān)于“C++內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字怎么使用”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

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

AI