国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【C++從0到1】新手都能看懂的C++入門(上篇),建議收藏

xcold / 2120人閱讀

摘要:上面這三種均不造成重載,現(xiàn)在來(lái)說(shuō)明原因。結(jié)論對(duì)于引用返回,返回的對(duì)象必須是棧幀銷毀后還存在的。全局,靜態(tài),未銷毀的函數(shù)棧幀當(dāng)中的都是可以的指針與引用如圖兩者底層實(shí)現(xiàn)差不多,引用是用指針模擬的。不建議聲明和定義分離,分離會(huì)導(dǎo)致鏈接錯(cuò)誤。


前言

C++入門是很多人頭疼的問(wèn)題,今日就與博主一同學(xué)習(xí)一些比較簡(jiǎn)單的基本概念,這些在之后很多地方的作用是十分大的。
看完之后,相信你會(huì)受益匪淺!!


一、命名空間

命名空間是什么,為什么要存在命名空間,首先我們?nèi)绻郧坝锌催^(guò)c++的代碼一定少不了這兩句。

#includeusing namespace std;

這個(gè)大家想必都看過(guò),using在這里實(shí)際上就是展開命名空間的內(nèi)容。

命名空間就是一個(gè)域,與外界隔離,使用域當(dāng)中的東西要通過(guò)(域名+::)

當(dāng)我們要使用當(dāng)前引入庫(kù)函數(shù)當(dāng)中的函數(shù)名作為變量時(shí),例如:如果我們引入頭文件#include,我們會(huì)發(fā)現(xiàn)我們使用rand作為變量名會(huì)出錯(cuò)

這是因?yàn)槲覀價(jià)and在stdlib中是作為一個(gè)函數(shù)存在的,我們?nèi)绻祟^文件,相當(dāng)于在預(yù)處理的時(shí)候就會(huì)將頭文件展開,我們就會(huì)看到rand作為函數(shù)的聲明及實(shí)現(xiàn)。

這個(gè)時(shí)候我們就無(wú)法使用這個(gè)rand,命名空間卻能幫我們解決

從上圖可以看出,命名空間不受到其他域當(dāng)中影響,因?yàn)樵谌钟蛘归_并不會(huì)影響到命名空間。但是如果我們不展開命名空間的話,調(diào)用命名空間內(nèi)部的函數(shù)時(shí)我們都要采用域限定符,所以我們?cè)谶M(jìn)行一些日常練習(xí)時(shí)才會(huì)去進(jìn)行命名空間的展開。

需要注意的就是,如果有同名的命名函數(shù),他們就會(huì)被合在一起。
對(duì)于命名空間,內(nèi)部也可以在嵌套定義命名空間,使用的時(shí)候也要注意加上域作用限定符。

總結(jié):我們使用命名空間的時(shí)候可以進(jìn)行部分展開,對(duì)于常用的函數(shù)展開,這是一種折中的解決方案。


二、缺省函數(shù)

常見(jiàn)使用

在模擬順序表的初始化的時(shí)候,我們可以用缺省參數(shù)控制我們要申請(qǐng)多大的空間,如果沒(méi)有傳參數(shù),我們可以默認(rèn)幫它設(shè)置。其中我們上面演示的為半缺省參數(shù)。

  1. 半缺省參數(shù)必須從右往左依次來(lái)給出,不能間隔著給
  2. 缺省參數(shù)不能在函數(shù)聲明和定義中同時(shí)出現(xiàn)

解釋第一條:因?yàn)槿绻麖淖箝_始給的話,如果我們左邊想要默認(rèn)的缺省值,就不合理了。
解釋第二條:倘若聲明和定義當(dāng)中給的缺省值不一樣,編輯器無(wú)法判斷,所以制止這種寫法,倘若要使用,則參照下圖。


三、 函數(shù)重載

3.1常見(jiàn)使用


剛剛談完的命名空間中一個(gè)域中不能出現(xiàn)重復(fù)的定義,但是c++在這里,允許了函數(shù)重載,只要函數(shù)的順序(不同類型之間),類型不同,都可以造成函數(shù)重載。

上面這三種均不造成重載,現(xiàn)在來(lái)說(shuō)明原因。原因與c++當(dāng)中為何支持函數(shù)重載有關(guān),相信看了下面你就能明白。


3.2重載底層實(shí)現(xiàn)

提前說(shuō)明,以下為linux的解釋說(shuō)明,并且文件后綴不代表他是否為cpp文件,而是根據(jù)我們所調(diào)用的編輯器決定的。
先說(shuō)結(jié)論:是因?yàn)樗麄兊暮瘮?shù)名修飾規(guī)則不同導(dǎo)致的。

我們先來(lái)看看linux下對(duì)于c的函數(shù)名和cpp當(dāng)中的函數(shù)名在編譯階段是怎樣的,這里我們用的是objudump -S,查看我們的.o文件

我們能在這里觀察到對(duì)于linux平臺(tái)下,鏈接時(shí)我們的函數(shù)是沒(méi)有經(jīng)過(guò)任何修飾的,通過(guò)這樣的函數(shù)名在鏈接的時(shí)候重定位將函數(shù)的地址再填進(jìn)去。在c中,這樣子當(dāng)我們重載的時(shí)候,兩個(gè)同名的add即便構(gòu)成重載,卻因?yàn)閮蓚€(gè)相同的add構(gòu)成了不確定導(dǎo)致無(wú)法進(jìn)行鏈接
而c++當(dāng)中對(duì)于函數(shù)進(jìn)行了修飾,并且它的修飾規(guī)則比較簡(jiǎn)單_Z是固定的前綴,3表示函數(shù)名的長(zhǎng)度,我們Add的長(zhǎng)度正好是3,而剩下的ii/dd則就是參數(shù)名稱。


3.3返回值不納入重載原因

那么有人可能會(huì)想,為什么設(shè)計(jì)的時(shí)候不把返回值也作為函數(shù)重載的依據(jù)呢,設(shè)想一下,假如我們?cè)诤瘮?shù)名前面假如返回值的首字母作為修飾函數(shù)名,下面這種情況是不是也是存在異議的,也就是我們底層設(shè)計(jì)的時(shí)候雖然是可以支持到函數(shù)返回值也來(lái)修飾函數(shù)名,從語(yǔ)法層面,編輯器不能通過(guò)此特征來(lái)判斷調(diào)用哪個(gè)函數(shù)。


四、extren C

我們?cè)谌粘V腥绻捎胏語(yǔ)言去寫一個(gè)項(xiàng)目,如果我們要利用c++庫(kù)的話,根據(jù)上面函數(shù)重載,我們c語(yǔ)言在鏈接時(shí)通過(guò)自己的函數(shù)名是沒(méi)辦法找到對(duì)應(yīng)的c++的函數(shù)名的,而c++在c語(yǔ)言后面誕生,所以采用c++寫的項(xiàng)目,調(diào)用c的庫(kù)的時(shí)候是可以直接找到的。所以我們編寫c++的庫(kù)的時(shí)候,為了照顧到我們用純c寫項(xiàng)目的,就會(huì)在該函數(shù)的聲明處加上extern “C”,這樣c++和c都能同時(shí)調(diào)到這個(gè)函數(shù)。

比如谷歌提供tcmalloc庫(kù)中就有若干函數(shù)如此。


五、引用

5.1常見(jiàn)使用


可以看出a為b的一個(gè)引用,別名,語(yǔ)法上是不占空間的,我們通過(guò)取地址也可以看出a和b指向的都是同一塊內(nèi)存。


引用的特點(diǎn):引用必須初始化。引用只能對(duì)一塊空間,不像指針可以轉(zhuǎn)換指向內(nèi)容。 一個(gè)變量可以有多個(gè)引用。


觀察下面代碼:

int main(){//這里是b賦值給a,還是a是b的引用呢?	int b = 10;	int& a = b;	int c = 20;	a = c;	return 0;}

答案揭曉:這里是b賦值給a。

因?yàn)槲覀兘酉聛?lái)要講到引用返回會(huì)遇到的種種情況,所以我們?cè)谶@里先講述臨時(shí)變量是一個(gè)怎樣的存在。


5.2臨時(shí)變量的作用

思考這里的ret是怎么返回回去的,在函數(shù)棧幀中提到了調(diào)用完函數(shù)之后,空間會(huì)被釋放,我們r(jià)eturn ret 的時(shí)候他是將ret返回嗎?不是的,因?yàn)閞et在Add的棧幀中,如果他返回就會(huì)造成空間的越界訪問(wèn)。那么他是如何返回的呢。

答案:當(dāng)返回的數(shù)據(jù)大小在4,8字節(jié)的情況下通常是由我們的寄存器eax帶回來(lái),如果超過(guò)這個(gè)范圍的話,就會(huì)在main函數(shù)的棧幀中提前開設(shè)一塊跟返回值的一份臨時(shí)拷貝。臨時(shí)數(shù)據(jù)具有常性。

帶回我們的結(jié)構(gòu)體做了若干操作,我們這里不詳細(xì)講解。對(duì)上面的答案進(jìn)行簡(jiǎn)單的論證。

強(qiáng)制類型轉(zhuǎn)換和隱式類型轉(zhuǎn)換都是會(huì)創(chuàng)建一個(gè)臨時(shí)變量進(jìn)行接受的,像下面這張圖,我們的r雖然是i的引用,但是他們卻不是指向同一塊空間的,而這里的r是指向誰(shuí)了呢?就是我們的一個(gè)臨時(shí)變量,臨時(shí)變量具有常性,我們不能對(duì)他進(jìn)行修改,所以我們要添加const表示只對(duì)該變量有讀取的權(quán)限!

常引用如下:

引用不是新定義一個(gè)變量,而是給已存在變量取了一個(gè)別名,編譯器不會(huì)為引用變量開辟內(nèi)存空間,它和它引用的變量共用同一塊內(nèi)存空間。

引用和指針在sizeof中含義不同:引用結(jié)果為引用類型的大小(與類型有關(guān)),但指針始終是地址空間所占字節(jié)個(gè)數(shù)(32位平臺(tái)下占4個(gè)字節(jié)),即與平臺(tái)有關(guān)。


5.3引用返回常見(jiàn)錯(cuò)誤

引用有作為參數(shù),和返回值的兩大作用,那么使用的時(shí)候返回值這塊容易犯錯(cuò)誤。

int& Add(int x, int y){	int ret = x + y;	return ret;}int main(){	int sum = Add(1, 2);	Add(3, 4);	cout << "Add(1,2): is " << sum << endl;	return 0;}

雖然上面的代碼運(yùn)行的結(jié)果是正確的,但是存在著很大的安全隱患,Add這個(gè)棧幀銷毀過(guò)后再去訪問(wèn),倘若系統(tǒng)對(duì)于回收的空間會(huì)進(jìn)行處理的話,這塊空間上的值就是隨機(jī)值,vs2019在這塊對(duì)于回收的內(nèi)存是沒(méi)有做處理的。

知道了上面的結(jié)論,再來(lái)看下面這段代碼:只改了這一處返回值,這時(shí)候會(huì)發(fā)生什么呢?



甚至當(dāng)你在Add那塊空間被cout給覆蓋之后,ret的內(nèi)存空間甚至有可能是一些奇奇怪怪的值。

結(jié)論:對(duì)于引用返回,返回的對(duì)象必須是棧幀銷毀后還存在的。全局,靜態(tài),未銷毀的函數(shù)棧幀當(dāng)中的都是可以的!!

5.4指針與引用

如圖:兩者底層實(shí)現(xiàn)差不多,引用是用指針模擬的。


六、內(nèi)聯(lián)函數(shù)

inline是一種以空間換時(shí)間的做法,省去調(diào)用函數(shù)額開銷。所以代碼很長(zhǎng)或者有循環(huán)/遞歸的函數(shù)不適宜 使用作為內(nèi)聯(lián)函數(shù)。
inline對(duì)于編譯器而言只是一個(gè)建議,編譯器會(huì)自動(dòng)優(yōu)化,如果定義為inline的函數(shù)體內(nèi)有循環(huán)/遞歸等 等,編譯器優(yōu)化時(shí)會(huì)忽略掉內(nèi)聯(lián)。
inline不建議聲明和定義分離,分離會(huì)導(dǎo)致鏈接錯(cuò)誤。因?yàn)閕nline被展開,就沒(méi)有函數(shù)地址了,鏈接就會(huì)找不到。

內(nèi)聯(lián)函數(shù)替代宏的原因

#define SWAP(T,m,n) {T s; s=m, m=n, n=s;}//#define Add(a,b) a+b//#define Add(a,b) (a+b)//#define Add(a,b) ((a)+(b))int main(){	int a = 0;	int b = 1;	//宏的本質(zhì)是替換,得看替換之后合不合理!!	//{T s; s=m, m=n, n=s;}	SWAP(int,a,b);	cout << a <<" "<< b << endl;	return 0;}

因?yàn)楹觌m然功能強(qiáng)大,但是在使用的時(shí)候缺少類型檢查,調(diào)試不方便,使用的比較別扭等因素,所以我們c++引入內(nèi)聯(lián)函數(shù),在調(diào)用的地方展開。但是對(duì)編輯器只是一種建議。
c++當(dāng)中建議用const,enum替換宏常量,內(nèi)聯(lián)函數(shù)替換宏函數(shù)。


七、nullptr


c++標(biāo)準(zhǔn)將NULL定義為0,通常情況下按照c語(yǔ)言,int* p=NULL,還是沒(méi)有錯(cuò)的,但是在下面這種情況會(huì)有異議。所以我們推薦c++當(dāng)中使用nullptr作為空指針。


總結(jié)

c++的入門就到這里啦,下一章會(huì)描述類和對(duì)象。
三連支持一下吧!!!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/121543.html

相關(guān)文章

  • 終于有一篇小白能懂的智能指針詳解了!

    摘要:在我以為我和緣分尚淺的時(shí)候,搬來(lái)救兵,智能指針橫空出世,打敗了內(nèi)存泄漏,拯救了我們的關(guān)系。智能指針引入了智能指針的概念,使用了引用計(jì)數(shù)的想法,讓程序員不再需要關(guān)心手動(dòng)釋放內(nèi)存。它還增加了一個(gè)成員函數(shù)用于交換兩個(gè)智能指針的值。 ...

    includecmath 評(píng)論0 收藏0
  • 我們一直談?wù)摗皩懘a”,但你會(huì)“讀代碼”嗎?

    摘要:只有能看懂代碼,你才能快速準(zhǔn)確地定位代碼中的問(wèn)題。要寫出很的代碼,少不了閱讀優(yōu)秀的源碼。我們的論壇和答疑群里,有一些同學(xué)會(huì)查看并解答其他人的代碼問(wèn)題。實(shí)際上,我覺(jué)得就是沒(méi)看懂你只是看懂了每一行代碼的意思,但并沒(méi)有理解整個(gè)代碼的設(shè)計(jì)。 編程,又被稱作 寫代碼 。這個(gè)說(shuō)法有可能會(huì)帶來(lái)一點(diǎn)點(diǎn)誤解,讓人覺(jué)得如何寫是學(xué)習(xí)編程要解決的主要問(wèn)題。但事實(shí)并非如此。盡管最終代碼要在鍵盤上敲出來(lái),但這個(gè)過(guò)...

    2i18ns 評(píng)論0 收藏0
  • 程序員如何自我學(xué)習(xí)?阿里資深技術(shù)專家這樣做

    摘要:而程序員和醫(yī)生律師的不同點(diǎn)在于持續(xù)學(xué)習(xí)上。兩個(gè)小問(wèn)題是需要收費(fèi),一年大概刀圖書都是英文的。的視頻基本都有英文字幕,配合作者的,英語(yǔ)不好的同學(xué)學(xué)習(xí)也沒(méi)有問(wèn)題。英文好的有技術(shù)功底的同學(xué)多發(fā)表一些觀點(diǎn),其他的同學(xué)都 摘要: 行業(yè)發(fā)展得太快,你必須學(xué)習(xí),純靠經(jīng)驗(yàn)積累行不通,技術(shù)淘汰的速度遠(yuǎn)大于你經(jīng)驗(yàn)積累的速度。 非雞湯:不要和程序員談自己的編程歷史,很多的經(jīng)驗(yàn)在今天已經(jīng)不適用了。只要2-3年...

    Jacendfeng 評(píng)論0 收藏0
  • 《大型網(wǎng)站系統(tǒng)與Java中間件》讀書筆記 (中)

    摘要:文本已收錄至我的倉(cāng)庫(kù),歡迎回顧上一篇大型網(wǎng)站系統(tǒng)與中間件讀書筆記一這周周末讀了第四章,現(xiàn)在過(guò)來(lái)做做筆記,希望能幫助到大家。沒(méi)錯(cuò),我們通過(guò)肯定是可以完成兩個(gè)系統(tǒng)之間的通信的問(wèn)題的。 前言 只有光頭才能變強(qiáng)。文本已收錄至我的GitHub倉(cāng)庫(kù),歡迎Star:https://github.com/ZhongFuCheng3y/3y 回顧上一篇: 《大型網(wǎng)站系統(tǒng)與Java中間件》讀書筆記(一)...

    fredshare 評(píng)論0 收藏0
  • 保姆級(jí)教程HTML兩萬(wàn)字筆記大總結(jié)【建議收藏】(上篇

    摘要:標(biāo)簽不區(qū)分大小寫,但推薦小寫。標(biāo)簽可以嵌套,但不能交叉嵌套。標(biāo)簽也稱為元素。比如行內(nèi)標(biāo)簽亦可成行內(nèi)元素。 ??HTML必備知識(shí)詳解?? 第一部分:HTML框架簡(jiǎn)介...

    paulli3 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<