最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

C++自制心得——開篇(缺省函數(shù)+函數(shù)重載)

2023-08-14 22:14 作者:這年頭起名可真不容易  | 我要投稿

前言:?

本心得只適合給那些擁有C語言基礎 (系統(tǒng)的自主學習過C語言(以找工作為目標,學校老師教的一律視作沒學),了解一些底層機制,用C實現(xiàn)過一些基本數(shù)據(jù)結(jié)構(gòu) (順序表、鏈表、隊列與棧、初等二叉樹、十大經(jīng)典排序等) ) 的人觀看。如果你不滿足上述條件就不要在這里浪費時間了。

本人在寫專欄上的技術力并不好,如果你覺得這篇文章在排版上有需要改進的地方可以在評論區(qū)留言并附上具體操作流程。

本人目前是大二在讀生,目前剛開始學習C++相關知識,如果有大佬發(fā)現(xiàn)哪里介紹的不對或者有疏漏歡迎在評論區(qū)留言,我盡量在發(fā)現(xiàn)的第一時間糾正。

好,廢話不多講,我們進入正題。?

缺省函數(shù)

test.cpp

slist.h

slist.cpp

這是一個簡單順序表的C代碼(.cpp環(huán)境下NULL有一些歷史遺留問題,換成了C++的nullptr),跑起來肯定沒問題,但是這里有個讓人不爽的地方。在slist.h里,我們用宏定義了一個默認初始化大小,一般情況下這個值是100,如果數(shù)據(jù)量多于這個值就會去擴容,這個邏輯看著還能接受。那如果出現(xiàn)了某些極端情況會怎么樣?讓代碼跑起來。

諸位可以回憶一下realloc函數(shù)的性質(zhì)

看看控制臺上滿屏幕的異地擴容,問題的嚴重性躍然紙上。哪怕不算頻繁拷貝帶來的性能浪費,這個方案所花費的時間也已經(jīng)達到了一步到位的近兩倍。顯然,在C語言里為了避免這一現(xiàn)象的發(fā)生,我們需要額外的函數(shù)來處理非默認情況下的空間開辟。

好吧,我承認我懶得再敲一個函數(shù),那么C++有沒有辦法用一個函數(shù)解決默認+非默認的情景?現(xiàn)在,請出我們的缺省函數(shù)(你可以認為缺省 == 默認),然后再跑一遍代碼。

毫無疑問的薄紗

slist.cpp(修改的部分)

slist.h

test.cpp

上面的代碼有點復雜,我們來看個簡單的。

test.cpp

打印結(jié)果

顯然,缺省函數(shù)比常規(guī)函數(shù)多了一個備胎機制,如果你給了值,缺省函數(shù)就用你的值,你不給值,缺省函數(shù)就用備胎的值。

全缺省函數(shù)

函數(shù)當然可以有多個缺省值,如果一個函數(shù)的所有形參均擁有缺省值,那它就是全缺省函數(shù),such as:

test.cpp

打印結(jié)果

我知道你想干什么,但是不行,你不能這么傳。

缺省函數(shù)存在多個缺省值時,只可從左向右傳參。

半缺省函數(shù)

常規(guī)形參與缺省形參也能一起用,這樣的函數(shù)也叫半缺省函數(shù)。

test.cpp

大膽的想法也可以收一收了,缺省函數(shù)存在多個缺省形參時,只可從右向左確定缺省形參,且所有的缺省形參必須在常規(guī)形參右邊。

缺省函數(shù)的聲明與定義

在復雜工程里把某些函數(shù)聲明單獨封裝到頭文件里應該是個常識,不過在缺省函數(shù)里聲明定義分離是個大坑,舉個例子:


你要是這么寫,直接報錯

(⊙o⊙)…為什么不能這么寫,你看看下面這張圖。

沒喝酒的程序猿肯定不會寫出這種東西

wow,聲明和定義居然不一樣,編譯器要用哪個?編譯器不想搭理你還在你臉上甩了兩個重定義錯誤。所以正確的做法是這樣的:

聲明處定義缺省形參,在定義處常規(guī)形參。至于為什么要在聲明處定義,很好理解。如果在定義處定義缺省形參,那么在傳參時部分傳法會與聲明沖突,結(jié)果就會報錯

那為什么編譯器可以通過缺省函數(shù)的聲明找到其定義,他們看上去可不太一樣,那就要用到函數(shù)重載的相關知識了。

函數(shù)重載

舉個例子,上面的Add函數(shù)要完成int + int的計算和double + double的計算,在C語言里只能給函數(shù)名加修飾符來區(qū)分,至于現(xiàn)在,上代碼。

(tips: 現(xiàn)在還不夠簡單,模板是終極解決方案)

所謂重載就是一詞多義,那么重載函數(shù)指的是函數(shù)名的一詞多義,這個概念應該很好理解。

如何構(gòu)成函數(shù)重載

1.形參類型不同

2.形參個數(shù)不同

3.形參順序不同

上述三個條件只需成立一個即可構(gòu)成函數(shù)重載。

注意事項:1. 對于第二點,與缺省函數(shù)聯(lián)用有可能出現(xiàn)調(diào)用歧義。

此時仍然構(gòu)成函數(shù)重載

? ? ? ? ? ? ? ? 2. 對于第三點,請注意交換順序的是形參類型,而非形參名。

? ? ? ? ? ? ? ? 3. 其他條件相同,返回值類型不同的同名函數(shù)不構(gòu)成函數(shù)重載。(一旦構(gòu)成函數(shù)重? ? ? ? ? ? ? ? ? ? ? 載,你可以修改任意重載函數(shù)的返回值類型,并不是指返回值類型不同的同名函? ? ? ? ? ? ? ? ? ? ? 數(shù)不構(gòu)成函數(shù)重載)

函數(shù)重載核心原理——函數(shù)名稱修飾

正兒八經(jīng)學習過C語言的人應該知道,把工程里的代碼轉(zhuǎn)化成可執(zhí)行文件分兩步,編譯(編譯器)+ 鏈接(鏈接器),其中編譯分為三步,預處理(去注釋,宏替換,頭文件展開,條件編譯),編譯(檢查語法,生成匯編代碼),匯編(形成符號表,生成機器碼),鏈接階段進行符號表的合并與重定位,合并段表。

這里我故意寫了一個bug,還把文件后綴改成了.c,所以在C環(huán)境下這里被紅框框起來的部分就是函數(shù)func在符號表里的樣子,現(xiàn)在讓我們用CPP環(huán)境再試一次。

vs2019的函數(shù)名修飾規(guī)則相當惡心,建議用g++查看

盡管vs2019的函數(shù)名修飾規(guī)則很奇葩,但它至少給了一點有用信息。C++符號表里的函數(shù)名多了很多修飾符,而且在上述例子中int,double位置的交換直接導致了N,H字母位置的交換。結(jié)論很明顯,C++在形成符號表的時候把形參以某種規(guī)則加入到函數(shù)名中,這樣做使得重載函數(shù)在符號表中的名字變的可以區(qū)分,如此一來重載函數(shù)也能擁有獨立地址,重載函數(shù)的自動匹配也就實現(xiàn)了。

現(xiàn)在我們就能回答缺省函數(shù)那里的問題了。因為函數(shù)名修飾規(guī)則不支持缺省參數(shù),所以在符號表里缺省函數(shù)的聲明與定義是一樣的,那么在鏈接的時候鏈接器會自動將聲明定義二合一,形成一個具有實際地址的函數(shù),這樣就不會出現(xiàn)鏈接錯誤了。

同理,重載函數(shù)不支持返回值重載也是因為函數(shù)名修飾規(guī)則不支持返回值,在符號表里就會出現(xiàn)兩個一樣的函數(shù)名,編譯器就會爆重定義錯誤。


這期的干貨很多,各位觀眾下去好好消化一下。下一期教程講引用,難度還要再加,諸位不要掉隊哦。


C++自制心得——開篇(缺省函數(shù)+函數(shù)重載)的評論 (共 條)

分享到微博請遵守國家法律
石阡县| 班戈县| 镇原县| 溧水县| 若尔盖县| 临高县| 天门市| 常熟市| 湾仔区| 曲阜市| 蕲春县| 夹江县| 金坛市| 朔州市| 包头市| 江陵县| 大洼县| 巫山县| 沅陵县| 嘉峪关市| 西丰县| 鹰潭市| 谷城县| 恩平市| 开远市| 新源县| 巨鹿县| 北辰区| 伊宁县| 黔西县| 竹溪县| 德钦县| 宜州市| 靖边县| 河西区| 海阳市| 尼玛县| 西安市| 策勒县| 富宁县| 淅川县|