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

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

C++自制心得——開篇(內(nèi)聯(lián)函數(shù))

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

前言:?

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

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

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

好,廢話不多講,我們進(jìn)入正題。

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

1. 宏函數(shù)與內(nèi)聯(lián)函數(shù)

在開始我們正式講解之前,先問一個(gè)小問題,怎么用宏函數(shù)寫一個(gè)Add?哎呀寫個(gè)Add,這不是章口就......?宏函數(shù),我想想,應(yīng)該是這樣的。

好像不對(duì),哦,我想起來了,宏是替換,不能加分號(hào)。

感覺...還少了點(diǎn)什么,對(duì),差一個(gè)括號(hào)。

完美,調(diào)試也沒出問題,就它了。

but,這還是錯(cuò)的,正確的寫法是這樣的。

它為什么這么寫,我相信大家心里都有數(shù)。但我估計(jì)如果不給正確示范老司機(jī)可能也會(huì)翻車。這就說明了宏函數(shù)的第一個(gè)問題,容易出現(xiàn)語法錯(cuò)誤。宏函數(shù)的第二個(gè)問題就是無法調(diào)試,更坑人。但宏函數(shù)也有一些好處,第一,沒有類型檢查更靈活,不過在后面我們會(huì)學(xué)模板,這個(gè)優(yōu)勢(shì)就等于不存在。第二,節(jié)省函數(shù)棧幀調(diào)用所導(dǎo)致的時(shí)間消耗。所以,為了解決宏函數(shù)的缺陷,內(nèi)聯(lián)函數(shù)應(yīng)運(yùn)而生。

這就是一個(gè)簡(jiǎn)單的內(nèi)聯(lián)函數(shù)的代碼,只需要在函數(shù)前面加上inline關(guān)鍵字就可以了。

內(nèi)聯(lián)函數(shù)解決了宏函數(shù)的所有問題,并保留了其可原地展開的優(yōu)點(diǎn)。首先,內(nèi)聯(lián)函數(shù)不可能寫出像宏一樣的語法問題,因?yàn)閮?nèi)聯(lián)函數(shù)除了前面的關(guān)鍵字,其余部分與函數(shù)完全一樣,而函數(shù)是我們?cè)缇蛯憼€的東西。其次,如果沒有人為修改編譯器設(shè)置,內(nèi)聯(lián)函數(shù)在debug模式下可以像常規(guī)函數(shù)一樣調(diào)試,只有在release模式下才會(huì)和宏一樣原地展開。

默認(rèn)情況下內(nèi)聯(lián)函數(shù)在debug模式下的匯編代碼
修改編譯器設(shè)置后在debug模式里調(diào)出來的內(nèi)聯(lián)函數(shù)的匯編代碼

對(duì)比一二兩張圖,很明顯第二張圖里沒有call語句(常規(guī)函數(shù)調(diào)用的關(guān)鍵指令),這說明使用內(nèi)聯(lián)函數(shù)確實(shí)不會(huì)建立函數(shù)棧幀。

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

這里要強(qiáng)調(diào)一點(diǎn),inline關(guān)鍵字只是一個(gè)請(qǐng)求,不是強(qiáng)制性的,也就是說,一個(gè)函數(shù)是不是內(nèi)聯(lián)函數(shù)需要經(jīng)過編譯器審核,一般情況下過長(zhǎng)的函數(shù)不會(huì)成為內(nèi)聯(lián)函數(shù),舉個(gè)例子:

看見那個(gè)醒目的call沒有

讓我們把代碼改短一點(diǎn)

編譯器這么做自然有它的理由,這里我們假設(shè)編譯器不會(huì)檢查內(nèi)聯(lián)函數(shù)展開后的匯編指令數(shù)目,再定義一個(gè)函數(shù)void func(),假設(shè)它展開有10000行匯編指令(假定函數(shù)在調(diào)用處展開與建立函數(shù)棧幀生成的匯編指令數(shù)相同(以這個(gè)函數(shù)的體量來說,這點(diǎn)不同完全可以忽略)),分別以內(nèi)聯(lián)函數(shù)與常規(guī)函數(shù)的形式調(diào)用100次,那么以常規(guī)函數(shù)形式調(diào)用只有10100行匯編指令(每個(gè)調(diào)用處只有一句call指令),以內(nèi)聯(lián)函數(shù)形式調(diào)用就會(huì)在每個(gè)調(diào)用處生成10000行匯編指令,加在一起就是1000000行,相差近100倍。這就會(huì)導(dǎo)致一個(gè)問題------代碼膨脹,最近原神不是新出了一個(gè)楓丹壓縮包,據(jù)說解壓后有60G,經(jīng)過這樣的反向優(yōu)化說不定就變成了80個(gè)G,得不償失。

其次,內(nèi)聯(lián)函數(shù)的聲明與定義與一般函數(shù)有所不同。

聲明和定義在同一文件內(nèi)當(dāng)然沒有問題

常規(guī)的跨文件調(diào)用會(huì)出現(xiàn)鏈接錯(cuò)誤。

test.cpp

test.h

inline.cpp

再來另一段代碼

test.cpp(修改后)

test.h(修改后)

inline.cpp(修改后)

這怎么就過了,上面的怎么就不行。還記得我們?cè)趦?nèi)聯(lián)函數(shù)與常規(guī)函數(shù)最大的區(qū)別嗎?不需要call指令,這就意味著內(nèi)聯(lián)函數(shù)的地址并不需要進(jìn)入符號(hào)表(call指令調(diào)用函數(shù)要用到函數(shù)地址),編譯器也是這么做的。但是,我們把內(nèi)聯(lián)函數(shù)的聲明與定義裝到了兩個(gè)不同的文件里,因此,鏈接器只能被迫在符號(hào)表里尋找內(nèi)聯(lián)函數(shù)的地址,結(jié)果可想而知,找不到。

在修改后的版本里,我們沒有直接跨文件調(diào)用內(nèi)聯(lián)函數(shù),而是通過常規(guī)函數(shù)作為橋梁,間接達(dá)到了跨文件調(diào)用內(nèi)聯(lián)函數(shù)的效果。不過,這個(gè)方案很挫,下面才是真正的解決方案。

test.h(二次再版)

inline.cpp(二次再版)

原理很簡(jiǎn)單,既然內(nèi)聯(lián)函數(shù)不能跨文件調(diào)用,那統(tǒng)一在文件內(nèi)調(diào)用不就行了,結(jié)果確實(shí)符合預(yù)期。

而且,因?yàn)閮?nèi)聯(lián)函數(shù)不進(jìn)入符號(hào)表的特性,因頭文件被多個(gè)源文件包含所導(dǎo)致的鏈接沖突問題并不會(huì)發(fā)生。

別急,再講一個(gè)運(yùn)算符重載,我們就有對(duì)象了,待會(huì)見。

C++自制心得——開篇(內(nèi)聯(lián)函數(shù))的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
贡嘎县| 平武县| 驻马店市| 新闻| 阳曲县| 波密县| 仁布县| 南投县| 娱乐| 红桥区| 罗源县| 江永县| 姚安县| 革吉县| 铅山县| 云阳县| 贵阳市| 怀化市| 乐业县| 汪清县| 安图县| 铅山县| 凤凰县| 厦门市| 阳高县| 广东省| 兴海县| 赫章县| 南安市| 剑阁县| 德令哈市| 富平县| 沛县| 定南县| 蒲城县| 枣庄市| 武乡县| 黎城县| 炉霍县| 新宁县| 安溪县|