国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C++初階(三)】引用&內(nèi)聯(lián)函數(shù)&auto關(guān)鍵字

這篇具有很好參考價(jià)值的文章主要介紹了【C++初階(三)】引用&內(nèi)聯(lián)函數(shù)&auto關(guān)鍵字。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

?前言

?1. 引用

? 1.1 引用的概念?

?1.2 引用的特性

?1.3 引用的權(quán)限

?1.4 引用的使用

?1.5 引用與指針的區(qū)別

2. 內(nèi)聯(lián)函數(shù)

2.1? 什么是內(nèi)聯(lián)函數(shù)

2.2? 內(nèi)聯(lián)函數(shù)的特性

?3. auto關(guān)鍵字

?3.1 auto簡(jiǎn)介

?3.2 auto使用規(guī)則

?3.3 auto不能使用的場(chǎng)景

4.? 基于范圍的for循環(huán)

?4.1 范圍for使用

?4.2 使用條件

5. C++空指針?

總結(jié)


?前言

????????在學(xué)習(xí)C語言時(shí),大家或許都被指針為難過,在使用指針時(shí)也存在各種問題,比如:空指針野指針問題(指針可以在任何時(shí)候指向任何地址,包括無效地址)。此外在C語言中函數(shù)調(diào)用時(shí),如果多次的調(diào)用同一函數(shù),創(chuàng)建大量的函數(shù)棧幀就會(huì)導(dǎo)致性能下降,對(duì)于這些缺點(diǎn),C++都進(jìn)行了優(yōu)化與改進(jìn)。那么本期的 “主角” 就是引用&內(nèi)聯(lián)函數(shù)。

【C++初階(三)】引用&內(nèi)聯(lián)函數(shù)&auto關(guān)鍵字,c++,經(jīng)驗(yàn)分享

?1. 引用

? 1.1 引用的概念?

?????????引用是C++中的一個(gè)重要概念,它是一個(gè)已存在變量的別名,引用不是新定義一個(gè)變量,編譯器不會(huì)為引用變量開辟內(nèi)存空間,它和它引用的變量共用同一塊內(nèi)存空間。對(duì)引用的操作實(shí)際上就是對(duì)原變量的操作。

引用的定義方式為:類型& 引用名 = 原變量名;?

?比如:

int main()
{
	int a = 1;
	int& b = a;
	a++;
	b++;//b++也就是a++

	cout << a << endl;//輸出3
	return 0;
}

注意:引用類型必須和引用實(shí)體是同種類型的。

?1.2 引用的特性

  • 引用必須初始化
  • 不占用額外空間(它引用的變量共用同一塊內(nèi)存空間)
  • 不能修改引用的綁定(引用一旦引用一個(gè)實(shí)體,就不能再引用其他實(shí)體)
  • 引用可作為函數(shù)參數(shù)和返回值?
int main()
{
	int a = 1;
	int b = a;
	
	//int& t;出現(xiàn)報(bào)錯(cuò)

	int& c = a;
	int& d = a;
	int& e = c;

	//地址相同
	cout << &a << endl;
	cout << &c << endl;
	cout << &d << endl;
	cout << &e << endl;
	return 0;
}

?1.3 引用的權(quán)限

?????????在C++中,引用的權(quán)限與指針類似,可以分為兩種權(quán)限:常量引用和非常量引用。

? ? ? ? ?常量引用:使用const修飾的引用被稱為常量引用。常量引用只能讀取被引用變量的值,不能修改被引用變量的值。

????????如果引用實(shí)體使用const修飾,那引用也必須使用const修飾。也就是權(quán)限可以被縮小,但不可以被放大。

比如:

int main()
{
	const int a = 1;
	//int& b = a;出現(xiàn)報(bào)錯(cuò),權(quán)限被放大
	    
     //權(quán)限要等大
    const int a = 1;
    const int& b = a;

    //權(quán)限可以縮小
    int c = 2;
    const int& d = c;

	return 0;
}

除此之外,在類型轉(zhuǎn)換時(shí)創(chuàng)建的臨時(shí)變量也具有常屬性。

int main()
{
	
	int i = 1;
	double j = i;

	//double& rj = i;//報(bào)錯(cuò)
	//類型轉(zhuǎn)換過程中
	//存在隱式轉(zhuǎn)換產(chǎn)生臨時(shí)變量,這里的臨時(shí)變量具有常性
	const double& rj = i;	

	return 0;
}

?1.4 引用的使用

? ??做參數(shù)

void Swap(int& x, int& y)
{
	int tmp = x;
	x = y;
	y = tmp;
}

?和指針相比

void Swap(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

?使用上更加簡(jiǎn)潔,并且引用的傳值效率也很高,比如我們傳值時(shí)傳一個(gè)較大的數(shù)組,傳值調(diào)用將一個(gè)很大內(nèi)存的數(shù)組轉(zhuǎn)換為數(shù)組地址傳過去(變?yōu)?字節(jié))

struct A{ int a[10000]; };
void Func1(A a){}
void Func2(A& a){}

?這些指針可以完成的工作,引用也可以完成。

? ?做返回值

int& Add(int a, int b)
{
	static int c = a + b;
	return c;
}

在之前我們先來理解一下傳值返回:

int Count()
{
	int n = 0;
	n++;

	return n;
}

int main()
{
	int ret = Count();

	cout << ret << endl;
    return 0;
}

? ? 這里返回的n是Count函數(shù)里的n嗎?答案不是,在C語言函數(shù)中,函數(shù)執(zhí)行結(jié)束函數(shù)內(nèi)創(chuàng)建的變量就會(huì)銷毀,所以這里返回的是Count()函數(shù)中變量n數(shù)值的拷貝(返回的是n的值(臨時(shí)變量),而不是n這個(gè)變量)。

int& Count()
{
	int n = 0;
	n++;

	return n;
}

? ? ? 如果使用引用做返回值,返回的就是n的別名,也可以理解為返回的就是n這個(gè)變量(會(huì)報(bào)警告:返回局部變量或臨時(shí)變量的地址: n)。這樣直接返回函數(shù)內(nèi)變量是很危險(xiǎn)的,因?yàn)楹瘮?shù)內(nèi)的n出了函數(shù)作用域就被銷毀了,再返回原本的n地址處的數(shù)據(jù),此時(shí)數(shù)據(jù)是不可控的。

int main()
{
	int& ret = Count();

	cout << ret << endl;//第一次輸出還是正常值1

	cout << ret << endl;//第二次輸出就變成隨機(jī)值了
}

?1.5 引用與指針的區(qū)別

?在語法概念上引用就是一個(gè)別名,沒有獨(dú)立空間,和其引用實(shí)體共用同一塊空間

int main()
{
	int a = 10;
	int& ra = a;
	cout << "&a = " << &a << endl;//輸出的地址相同
	cout << "&ra = " << &ra << endl;
	return 0;
}

?在底層實(shí)現(xiàn)上實(shí)際是有空間的,因?yàn)?strong>引用是按照指針方式來實(shí)現(xiàn)的

?下邊是引用與指針底層匯編的對(duì)比:

【C++初階(三)】引用&內(nèi)聯(lián)函數(shù)&auto關(guān)鍵字,c++,經(jīng)驗(yàn)分享

引用與指針的不同點(diǎn):

  1. 引用概念上定義一個(gè)變量的別名,指針存儲(chǔ)一個(gè)變量地址。
  2. 引用在定義時(shí)必須初始化,指針沒有要求
  3. 引用在初始化時(shí)引用一個(gè)實(shí)體后,就不能再引用其他實(shí)體,而指針可以在任何時(shí)候指向任何一個(gè)同類型實(shí)體
  4. 沒有NULL引用,但有NULL指針
  5. 在sizeof中含義不同:引用結(jié)果為引用類型的大小,但指針始終是地址空間所占字節(jié)個(gè)數(shù)(32
    位平臺(tái)下占4個(gè)字節(jié))
  6. 引用自加即引用的實(shí)體增加1,指針自加即指針向后偏移一個(gè)類型的大小
  7. 有多級(jí)指針,但是沒有多級(jí)引用
  8. 訪問實(shí)體方式不同,指針需要顯式解引用,引用編譯器自己處理
  9. 引用比指針使用起來相對(duì)更安全

2. 內(nèi)聯(lián)函數(shù)

2.1? 什么是內(nèi)聯(lián)函數(shù)

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

【C++初階(三)】引用&內(nèi)聯(lián)函數(shù)&auto關(guān)鍵字,c++,經(jīng)驗(yàn)分享

?如上圖,函數(shù)在調(diào)用時(shí)并沒有創(chuàng)建函數(shù)棧幀,而是直接在main函數(shù)內(nèi)部展開。

2.2? 內(nèi)聯(lián)函數(shù)的特性

  • inline是一種以空間換時(shí)間的做法,如果編譯器將函數(shù)當(dāng)成內(nèi)聯(lián)函數(shù)處理,在編譯階段,會(huì)用函數(shù)體替換函數(shù)調(diào)用

缺陷:可能會(huì)使目標(biāo)文件變大,

優(yōu)勢(shì):少了調(diào)用開銷,提高程序運(yùn)行效率.

?但也并不是所有的函數(shù)都要展開,內(nèi)聯(lián)函數(shù)展開的也只適用于較小的函數(shù)。

比如:

????????一個(gè)函數(shù)有100行代碼,被調(diào)用了1000次,每次都展開,那就是10w行代碼,產(chǎn)生的文件要多大,而如果是函數(shù)棧幀調(diào)用,每次調(diào)用都去同一塊空間調(diào)用函數(shù),也就只多了100行代碼。

  • ?inline對(duì)于編譯器而言只是一個(gè)建議,不同編譯器關(guān)于inline實(shí)現(xiàn)機(jī)制可能不同,一般建議:將函數(shù)規(guī)模較小(即函數(shù)不是很長(zhǎng),具體沒有準(zhǔn)確的說法,取決于編譯器內(nèi)部實(shí)現(xiàn))、不是遞歸、且頻繁調(diào)用的函數(shù)采用inline修飾,否則編譯器會(huì)忽略inline特性

?內(nèi)聯(lián)函數(shù)只是向編譯器發(fā)送一個(gè)請(qǐng)求,編譯器可以選擇忽略

  • ?聲明和定義分離時(shí)不可以使用內(nèi)聯(lián)函數(shù)

?分離會(huì)導(dǎo)致鏈接錯(cuò)誤。因?yàn)閕nline被展開,就沒有函數(shù)地址了,鏈接就會(huì)找不到

內(nèi)聯(lián)函數(shù)在聲明和定義分離時(shí),直接調(diào)用會(huì)出現(xiàn)報(bào)錯(cuò),但是可以間接調(diào)用。

//fun.h
inline void fun()
{
	cout << "hello ,world!" << endl;
}

//fun.c
void func()
{
	fun();
}

//test.c
int main()
{
	fun();
	return 0;
}

?這種情況是可以正常調(diào)用的。

?3. auto關(guān)鍵字

?隨著程序越來越復(fù)雜,程序中用到的類型也越來越復(fù)雜,經(jīng)常體現(xiàn)在:

  • 類型難于拼寫
  • 含義不明確導(dǎo)致容易出錯(cuò)

?3.1 auto簡(jiǎn)介

????????使用auto修飾的變量,是具有自動(dòng)存儲(chǔ)器的局部變量 ,但是在日常中卻很少使用。

????????C++11中,標(biāo)準(zhǔn)委員會(huì)賦予了auto全新的含義即:auto不再是一個(gè)存儲(chǔ)類型指示符,而是作為一個(gè)新的類型指示符來指示編譯器,auto聲明的變量必須由編譯器在編譯時(shí)期推導(dǎo)而得。

?比如:

int Test()
{
	return 10;
}
int main()
{
	int a = 10;
	auto b = a;
	auto c = 'a';
	auto d = Test();
	cout << typeid(b).name() << endl;//int
	cout << typeid(c).name() << endl;//char
	cout << typeid(d).name() << endl;//int
	
	return 0;
}

auto會(huì)自動(dòng)讀取類型,并且使用auto定義變量時(shí)必須對(duì)其進(jìn)行初始化

注意:

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

?3.2 auto使用規(guī)則

  • ?與指針引用結(jié)合使用

?用auto聲明指針類型時(shí),用auto和auto*沒有任何區(qū)別,但用auto聲明引用類型時(shí)則必須加&

int main()
{
	int x = 10;
	auto a = &x;
	auto* b = &x;
	auto& c = x;
	cout << typeid(a).name() << endl;//int*
	cout << typeid(b).name() << endl;//int*
	cout << typeid(c).name() << endl;//int

	return 0;
}
  • 一行定義多個(gè)變量

????????當(dāng)在同一行聲明多個(gè)變量時(shí),這些變量必須是相同的類型,否則編譯器將會(huì)報(bào)錯(cuò),因?yàn)榫幾g
器實(shí)際只對(duì)第一個(gè)類型進(jìn)行推導(dǎo),然后用推導(dǎo)出來的類型定義其他變量。

auto a = 1, b = 2;
auto c = 3, d = 4.0; ?// 該行代碼會(huì)編譯失敗,因?yàn)閏和d的初始化類型不同

?3.3 auto不能使用的場(chǎng)景

  • ?auto不能作為函數(shù)返回類型

最新的C++語法是可以的,但是很不推薦,在日常應(yīng)用場(chǎng)景中一定不要這樣寫,在較大的項(xiàng)目中大多數(shù)都是多人合作的,如果你使用auto,那別人在調(diào)用你的函數(shù)接口時(shí)不知道返回類型很難搞,如果別人也用auto,這樣就會(huì)導(dǎo)致一系列連鎖,最后代碼越寫越 “ 屎山 ”,這就是典型的 “ 坑隊(duì)友 ”,要養(yǎng)成良好的代碼風(fēng)格。

  • ?auto不能作為函數(shù)的參數(shù)
void TestAuto(auto a)//出現(xiàn)報(bào)錯(cuò),編譯器無法對(duì)a的實(shí)際類型進(jìn)行推導(dǎo)
{

}
int main()
{
	TestAuto(2);
}
  • auto不能直接聲明數(shù)組

?【C++初階(三)】引用&內(nèi)聯(lián)函數(shù)&auto關(guān)鍵字,c++,經(jīng)驗(yàn)分享

4.? 基于范圍的for循環(huán)

?4.1 范圍for使用

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
    //正常的for循環(huán)遍歷
	for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
	{
		cout << arr[i] << ' ';
	}
	cout << endl;
    //范圍for遍歷
	for (int e : arr)
	{
		cout << e << ' ';//這里的e是數(shù)組值的拷貝,改變e無法改變數(shù)組的數(shù)據(jù)
	}
	return 0;
}

?????????對(duì)于一個(gè)有范圍的集合而言,由程序員來說明循環(huán)的范圍是多余的,有時(shí)候還會(huì)容易犯錯(cuò)誤。因此C++11中引入了基于范圍的for循環(huán)。for循環(huán)后的括號(hào)由冒號(hào)“ :”分為兩部分:第一部分是范圍內(nèi)用于迭代的變量,第二部分則表示被迭代的范圍。

?注意:范圍for與普通循環(huán)類似,可以用continue來結(jié)束本次循環(huán),也可以用break來跳出整個(gè)循環(huán)。

?4.2 使用條件

  • for循環(huán)迭代的范圍必須是確定的?
void TestFor(int array[])
{
??for(auto& e : array)
????cout<< e <<endl;
}

????????例如上述代碼,范圍并不明確。對(duì)于數(shù)組而言,就是數(shù)組中第一個(gè)元素和最后一個(gè)元素的范圍;對(duì)于類而言,應(yīng)該提供begin和end的方法,begin和end就是for循環(huán)迭代的范圍

5. C++空指針?

????????在C語言中我們常用的都是NULL來代表空指針,NULL實(shí)際是一個(gè)宏,在傳統(tǒng)的C頭文件(stddef.h)中,可以看到如下代碼:?

#ifndef NULL

#ifdef __cplusplus

#define NULL ?0

#else

#define NULL ?((void *)0)

#endif

#endif

可以看到,NULL可能被定義為字面常量0,或者被定義為無類型指針(void*)的常量。不論采取何
種定義,在使用空值的指針時(shí),都不可避免的會(huì)遇到一些麻煩?。我們可以使用C++代碼測(cè)試一下:

void f(int)
{
	cout << "f(int)" << endl;
}
void f(int*)
{
	cout << "f(int*)" << endl;
}
int main()
{
	f(0);			//f(int)
	f(NULL);		//f(int)
	f((int*)NULL);	//f(int*)
	return 0;
}

?不難發(fā)現(xiàn)NULL在C++中被替換成了0,在C++98中,字面常量0既可以是一個(gè)整形數(shù)字,也可以是無類型的指針(void*)常量,但是編譯器默認(rèn)情況下將其看成是一個(gè)整形常量,如果要將其按照指針方式來使用,必須對(duì)其進(jìn)行強(qiáng)轉(zhuǎn)(void*)0。

為了保險(xiǎn)起見,C++引入nullptr,代表空指針,在后續(xù)表示指針空值時(shí)建議最好使用nullptr。


總結(jié)

? ? ? ? 到本期C++的一些入門簡(jiǎn)單語法已經(jīng)基本介紹完畢,后續(xù)將會(huì)繼續(xù)深入學(xué)習(xí)C++,以上便是本期全部?jī)?nèi)容?,最后,感謝閱讀!文章來源地址http://www.zghlxwxcb.cn/news/detail-715130.html

到了這里,關(guān)于【C++初階(三)】引用&內(nèi)聯(lián)函數(shù)&auto關(guān)鍵字的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包