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

資訊專欄INFORMATION COLUMN

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

xcold / 2132人閱讀

摘要:上面這三種均不造成重載,現在來說明原因。結論對于引用返回,返回的對象必須是棧幀銷毀后還存在的。全局,靜態,未銷毀的函數棧幀當中的都是可以的指針與引用如圖兩者底層實現差不多,引用是用指針模擬的。不建議聲明和定義分離,分離會導致鏈接錯誤。


前言

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


一、命名空間

命名空間是什么,為什么要存在命名空間,首先我們如果以前有看過c++的代碼一定少不了這兩句。

#includeusing namespace std;

這個大家想必都看過,using在這里實際上就是展開命名空間的內容。

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

當我們要使用當前引入庫函數當中的函數名作為變量時,例如:如果我們引入頭文件#include,我們會發現我們使用rand作為變量名會出錯

這是因為我們rand在stdlib中是作為一個函數存在的,我們如果引了頭文件,相當于在預處理的時候就會將頭文件展開,我們就會看到rand作為函數的聲明及實現。

這個時候我們就無法使用這個rand,命名空間卻能幫我們解決

從上圖可以看出,命名空間不受到其他域當中影響,因為在全局域展開并不會影響到命名空間。但是如果我們不展開命名空間的話,調用命名空間內部的函數時我們都要采用域限定符,所以我們在進行一些日常練習時才會去進行命名空間的展開。

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

總結:我們使用命名空間的時候可以進行部分展開,對于常用的函數展開,這是一種折中的解決方案。


二、缺省函數

常見使用

在模擬順序表的初始化的時候,我們可以用缺省參數控制我們要申請多大的空間,如果沒有傳參數,我們可以默認幫它設置。其中我們上面演示的為半缺省參數。

  1. 半缺省參數必須從右往左依次來給出,不能間隔著給
  2. 缺省參數不能在函數聲明和定義中同時出現

解釋第一條:因為如果從左開始給的話,如果我們左邊想要默認的缺省值,就不合理了。
解釋第二條:倘若聲明和定義當中給的缺省值不一樣,編輯器無法判斷,所以制止這種寫法,倘若要使用,則參照下圖。


三、 函數重載

3.1常見使用


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

上面這三種均不造成重載,現在來說明原因。原因與c++當中為何支持函數重載有關,相信看了下面你就能明白。


3.2重載底層實現

提前說明,以下為linux的解釋說明,并且文件后綴不代表他是否為cpp文件,而是根據我們所調用的編輯器決定的。
先說結論:是因為他們的函數名修飾規則不同導致的。

我們先來看看linux下對于c的函數名和cpp當中的函數名在編譯階段是怎樣的,這里我們用的是objudump -S,查看我們的.o文件

我們能在這里觀察到對于linux平臺下,鏈接時我們的函數是沒有經過任何修飾的,通過這樣的函數名在鏈接的時候重定位將函數的地址再填進去。在c中,這樣子當我們重載的時候,兩個同名的add即便構成重載,卻因為兩個相同的add構成了不確定導致無法進行鏈接
而c++當中對于函數進行了修飾,并且它的修飾規則比較簡單_Z是固定的前綴,3表示函數名的長度,我們Add的長度正好是3,而剩下的ii/dd則就是參數名稱。


3.3返回值不納入重載原因

那么有人可能會想,為什么設計的時候不把返回值也作為函數重載的依據呢,設想一下,假如我們在函數名前面假如返回值的首字母作為修飾函數名,下面這種情況是不是也是存在異議的,也就是我們底層設計的時候雖然是可以支持到函數返回值也來修飾函數名,從語法層面,編輯器不能通過此特征來判斷調用哪個函數。


四、extren C

我們在日常中如果采用c語言去寫一個項目,如果我們要利用c++庫的話,根據上面函數重載,我們c語言在鏈接時通過自己的函數名是沒辦法找到對應的c++的函數名的,而c++在c語言后面誕生,所以采用c++寫的項目,調用c的庫的時候是可以直接找到的。所以我們編寫c++的庫的時候,為了照顧到我們用純c寫項目的,就會在該函數的聲明處加上extern “C”,這樣c++和c都能同時調到這個函數。

比如谷歌提供tcmalloc庫中就有若干函數如此。


五、引用

5.1常見使用


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


引用的特點:引用必須初始化。引用只能對一塊空間,不像指針可以轉換指向內容。 一個變量可以有多個引用。


觀察下面代碼:

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

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

因為我們接下來要講到引用返回會遇到的種種情況,所以我們在這里先講述臨時變量是一個怎樣的存在。


5.2臨時變量的作用

思考這里的ret是怎么返回回去的,在函數棧幀中提到了調用完函數之后,空間會被釋放,我們return ret 的時候他是將ret返回嗎?不是的,因為ret在Add的棧幀中,如果他返回就會造成空間的越界訪問。那么他是如何返回的呢。

答案:當返回的數據大小在4,8字節的情況下通常是由我們的寄存器eax帶回來,如果超過這個范圍的話,就會在main函數的棧幀中提前開設一塊跟返回值的一份臨時拷貝。臨時數據具有常性。

帶回我們的結構體做了若干操作,我們這里不詳細講解。對上面的答案進行簡單的論證。

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

常引用如下:

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

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


5.3引用返回常見錯誤

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

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;}

雖然上面的代碼運行的結果是正確的,但是存在著很大的安全隱患,Add這個棧幀銷毀過后再去訪問,倘若系統對于回收的空間會進行處理的話,這塊空間上的值就是隨機值,vs2019在這塊對于回收的內存是沒有做處理的。

知道了上面的結論,再來看下面這段代碼:只改了這一處返回值,這時候會發生什么呢?



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

結論:對于引用返回,返回的對象必須是棧幀銷毀后還存在的。全局,靜態,未銷毀的函數棧幀當中的都是可以的!!

5.4指針與引用

如圖:兩者底層實現差不多,引用是用指針模擬的。


六、內聯函數

inline是一種以空間換時間的做法,省去調用函數額開銷。所以代碼很長或者有循環/遞歸的函數不適宜 使用作為內聯函數。
inline對于編譯器而言只是一個建議,編譯器會自動優化,如果定義為inline的函數體內有循環/遞歸等 等,編譯器優化時會忽略掉內聯。
inline不建議聲明和定義分離,分離會導致鏈接錯誤。因為inline被展開,就沒有函數地址了,鏈接就會找不到。

內聯函數替代宏的原因

#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;	//宏的本質是替換,得看替換之后合不合理!!	//{T s; s=m, m=n, n=s;}	SWAP(int,a,b);	cout << a <<" "<< b << endl;	return 0;}

因為宏雖然功能強大,但是在使用的時候缺少類型檢查,調試不方便,使用的比較別扭等因素,所以我們c++引入內聯函數,在調用的地方展開。但是對編輯器只是一種建議。
c++當中建議用const,enum替換宏常量,內聯函數替換宏函數。


七、nullptr


c++標準將NULL定義為0,通常情況下按照c語言,int* p=NULL,還是沒有錯的,但是在下面這種情況會有異議。所以我們推薦c++當中使用nullptr作為空指針。


總結

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

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/121543.html

相關文章

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

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

    includecmath 評論0 收藏0
  • 我們一直談論“寫代碼”,但你會“讀代碼”嗎?

    摘要:只有能看懂代碼,你才能快速準確地定位代碼中的問題。要寫出很的代碼,少不了閱讀優秀的源碼。我們的論壇和答疑群里,有一些同學會查看并解答其他人的代碼問題。實際上,我覺得就是沒看懂你只是看懂了每一行代碼的意思,但并沒有理解整個代碼的設計。 編程,又被稱作 寫代碼 。這個說法有可能會帶來一點點誤解,讓人覺得如何寫是學習編程要解決的主要問題。但事實并非如此。盡管最終代碼要在鍵盤上敲出來,但這個過...

    2i18ns 評論0 收藏0
  • 程序員如何自我學習?阿里資深技術專家這樣做

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

    Jacendfeng 評論0 收藏0
  • 《大型網站系統與Java中間件》讀書筆記 (中)

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

    fredshare 評論0 收藏0
  • 保姆級教程HTML兩萬字筆記大總結【建議收藏】(上篇

    摘要:標簽不區分大小寫,但推薦小寫。標簽可以嵌套,但不能交叉嵌套。標簽也稱為元素。比如行內標簽亦可成行內元素。 ??HTML必備知識詳解?? 第一部分:HTML框架簡介...

    paulli3 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<