- 類型轉(zhuǎn)換
- 隱式類型轉(zhuǎn)換
又稱自動(dòng)類型轉(zhuǎn)換糊肤,它是由編譯器自動(dòng)進(jìn)行的。轉(zhuǎn)換的規(guī)則按'存儲(chǔ)空間提升原則'進(jìn)行啰扛,即存儲(chǔ)空間小的類型轉(zhuǎn)換成存儲(chǔ)空間大的類型嚎京,或精度低的類型轉(zhuǎn)換成精度高的類型,以保證運(yùn)算結(jié)果盡可能精確隐解。
char,short -> int -> unsigned -> long -> double
float -> double - 顯式類型轉(zhuǎn)換
人為進(jìn)行強(qiáng)制類型轉(zhuǎn)換鞍帝,如(int) (x+y)
- 參數(shù)傳遞機(jī)制
- 值傳遞
形參作為被調(diào)函數(shù)的內(nèi)部變量來處理,即開辟內(nèi)存空間以存放由主調(diào)函數(shù)復(fù)制過來的實(shí)參的值煞茫,從而成為實(shí)參的一個(gè)副本帕涌。值傳遞的特點(diǎn)是被調(diào)函數(shù)對形參的任何操作都是對內(nèi)部變量進(jìn)行的摄凡,不會(huì)影響到主調(diào)函數(shù)的實(shí)參變量的值。 - 引用傳遞
被調(diào)函數(shù)的形參雖然也作為內(nèi)部變量開辟了內(nèi)存空間蚓曼,但是這時(shí)存放的是由主調(diào)函數(shù)復(fù)制過來的實(shí)參的內(nèi)存地址亲澡,從而使得形參為實(shí)參的一個(gè)別名(形參和實(shí)參的內(nèi)存地址相同,則它們是同一個(gè)對象的兩個(gè)名稱)纫版。被調(diào)函數(shù)對形參的任何操作實(shí)際上都是對主調(diào)函數(shù)的實(shí)參進(jìn)行操作床绪。
- 函數(shù)調(diào)用棧
函數(shù)調(diào)用時(shí),為了能將參數(shù)傳遞到函數(shù)中其弊,準(zhǔn)確地返回到調(diào)用點(diǎn)以及返回函數(shù)值癞己,使用棧來管理存儲(chǔ)器。
系統(tǒng)為每次函數(shù)調(diào)用在棧中建立獨(dú)立的椝蠓ィ框架痹雅,稱為函數(shù)調(diào)用棧幀,其建立和撤銷是自動(dòng)維護(hù)的糊识。
函數(shù)調(diào)用約定最右邊的實(shí)參最先進(jìn)棧练慕。 - const參數(shù)和可變參數(shù)
const限定一個(gè)對象不允許被修改。
函數(shù)參數(shù)使用const限定的目的是確保形參對應(yīng)的實(shí)參對象在函數(shù)體中不會(huì)被修改技掏。對于基本類型的參數(shù),實(shí)參和形參本來就不是同一個(gè)內(nèi)存單元项鬼,互不影響哑梳,不用加const。但是如果是數(shù)組參數(shù)绘盟,指針參數(shù)就有必要了鸠真。
形參至少需要第一個(gè)參數(shù)是普通形參,后面用三個(gè)點(diǎn)表示可變參數(shù)龄毡,且只能位于函數(shù)形參列表的最后吠卷。 - 內(nèi)聯(lián)函數(shù)
函數(shù)調(diào)用時(shí)參數(shù)需要入棧,調(diào)用前需要保護(hù)現(xiàn)場并保存返回地址沦零,調(diào)用后需要恢復(fù)現(xiàn)場并按原來保存的返回地址繼續(xù)執(zhí)行祭隔。因此函數(shù)調(diào)用需要時(shí)間和空間開銷,影響執(zhí)行效率路操。
C++提供一種提高函數(shù)效率的方法疾渴,即在編譯時(shí)將被調(diào)函數(shù)的代碼直接嵌入到主調(diào)函數(shù)中,取消調(diào)用這個(gè)環(huán)節(jié)屯仗。這種嵌入到主調(diào)函數(shù)中的函數(shù)稱為內(nèi)聯(lián)函數(shù)搞坝,在函數(shù)定義的類型前加inline修飾符。
內(nèi)聯(lián)函數(shù)是以目標(biāo)代碼的增加為代價(jià)來換取運(yùn)行時(shí)間的節(jié)省魁袜。內(nèi)聯(lián)函數(shù)中不允許用循環(huán)語句和switch語句桩撮,遞歸函數(shù)也不能被用來做內(nèi)聯(lián)函數(shù)敦第。 - 帶默認(rèn)參數(shù)的函數(shù)
默認(rèn)參數(shù)在函數(shù)聲明或者函數(shù)定義中只能設(shè)置一次,也就是編譯器見到過一次函數(shù)設(shè)置默認(rèn)參數(shù)店量,后面就不允許再次出現(xiàn)這個(gè)函數(shù)的默認(rèn)參數(shù)設(shè)置芜果。
可以設(shè)置多個(gè)默認(rèn)參數(shù),但是設(shè)置順序?yàn)樽杂蚁蜃蟆?br> 默認(rèn)參數(shù)允許同一個(gè)函數(shù)名有多種調(diào)用方法垫桂。 - 函數(shù)重載
在同一個(gè)域中的同一個(gè)函數(shù)名可以用來定義多個(gè)函數(shù)师幕,但函數(shù)參數(shù)列表應(yīng)彼此不同:參數(shù)個(gè)數(shù)不同,參數(shù)類型不同诬滩,或者兩者均不同霹粥。
編譯器根據(jù)參數(shù)類型和參數(shù)個(gè)數(shù)自動(dòng)解析決定調(diào)用哪個(gè)版本的重載函數(shù)。 - 函數(shù)模板
函數(shù)模板定義一個(gè)通用型函數(shù)疼鸟,這些函數(shù)與類型無關(guān)后控,并且只在需要時(shí)自行實(shí)例化,從而形成批量型的編程方式空镜。
定義語法:
template<模板形參表> 返回類型 函數(shù)名(形式參數(shù)列表)
{
函數(shù)體
}
template<typename T>T add(T a, T b)
{
return a+b
}
- 函數(shù)調(diào)用形式
嵌套調(diào)用:在調(diào)用一個(gè)函數(shù)的過程中該函數(shù)又調(diào)用另一個(gè)函數(shù)浩淘,稱為函數(shù)嵌套調(diào)用。
遞歸調(diào)用:函數(shù)直接或間接調(diào)用自己吴攒≌懦可以這樣理解函數(shù)調(diào)用自己:實(shí)際上它在調(diào)用自身的一個(gè)副本,該副本是具有不同參數(shù)的另一個(gè)函數(shù)洼怔,任何時(shí)候只有一個(gè)副本是活動(dòng)的署惯,其余的都將被掛起。 - 作用域
局部變量:在函數(shù)內(nèi)部或復(fù)合語句中定義的變量镣隶。局部變量只能在定義它的區(qū)域及其子區(qū)域中使用极谊。
全局變量:在函數(shù)外部定義的變量。全部變量的有效區(qū)域是從定義變量的位置開始到源文件結(jié)束安岂。
可以使用extern聲明將變量或函數(shù)實(shí)體的可見區(qū)域往前延伸轻猖,稱為前置聲明。
在全局作用域中域那,變量或函數(shù)實(shí)體若使用static修飾咙边,則該實(shí)體對于其他源文件是屏蔽的,稱為私有的(private)次员。 - 程序映像和內(nèi)存布局
C++源程序經(jīng)過編譯和鏈接后样眠,成為二進(jìn)制形式的可執(zhí)行文件,稱為程序映像翠肘。運(yùn)行程序時(shí)檐束,由操作系統(tǒng)將可執(zhí)行文件裝入計(jì)算機(jī)內(nèi)存中,成為一個(gè)進(jìn)程束倍,程序在內(nèi)存中的布局由5個(gè)段組成(內(nèi)存地址由低到高):
代碼段
代碼段存放程序執(zhí)行的機(jī)器指令被丧,可共享用來被頻繁執(zhí)行盟戏,通常是只讀的防止被意外的修改。已初始化的數(shù)據(jù)段
存放C++程序中所有已賦初值的全局和靜態(tài)變量甥桂、對象柿究,也包括字符串、數(shù)組等常量黄选,但是基本類型的常量不包含在其中蝇摸,因?yàn)檫@些常量被編譯成指令的一部分存放在代碼段中。該段存儲(chǔ)單元的初始值在程序沒有運(yùn)行時(shí)就固定下來了办陷,在程序運(yùn)行時(shí)沒有初始化操作貌夕。未初始化的數(shù)據(jù)段
存放C++程序中所有未賦初值的全局和靜態(tài)變量,數(shù)據(jù)值全都初始化為0民镜。棧
放C++程序中所有局部的非靜態(tài)型變量啡专、臨時(shí)變量、包含函數(shù)形參和返回值制圈。
在程序映像中沒有棧们童,在程序開始運(yùn)行時(shí)也不會(huì)分配棧。函數(shù)調(diào)用時(shí)開始得到分配鲸鹦,將函數(shù)椈劭猓框架入棧,函數(shù)調(diào)用結(jié)束時(shí)釋放空間馋嗜,變量不存在完沪。-
堆
存放C++程序中動(dòng)態(tài)分配的存儲(chǔ)空間。
在程序映像中沒有堆嵌戈,在程序開始運(yùn)行時(shí)也不會(huì)分配堆,函數(shù)調(diào)用時(shí)也不會(huì)分配堆听皿。堆的存儲(chǔ)空間是由程序員使用指令分配和釋放熟呛。堆和棧的共同點(diǎn)是動(dòng)態(tài)存儲(chǔ),處于這兩個(gè)區(qū)域的存儲(chǔ)單元可以隨時(shí)分配和釋放尉姨,呈現(xiàn)臨時(shí)性的特點(diǎn)庵朝。區(qū)別是分配方式不同,棧是編譯器根據(jù)程序代碼自動(dòng)確定大小又厉,到函數(shù)調(diào)用時(shí)由指令自動(dòng)完成分配和釋放九府;堆則完全由程序員指定分配大小,何時(shí)分配覆致,何時(shí)釋放侄旬,自行掌握分配和釋放時(shí)機(jī),假如已經(jīng)釋放了還使用堆會(huì)產(chǎn)生引用錯(cuò)誤煌妈,或者始終沒有釋放會(huì)產(chǎn)生內(nèi)存泄露儡羔。
內(nèi)存溢出:程序在申請內(nèi)存時(shí)宣羊,沒有足夠的內(nèi)存空間可使用。你要求分配的內(nèi)存超出了系統(tǒng)能給你的汰蜘。
內(nèi)存泄露:程序動(dòng)態(tài)申請的堆內(nèi)存由于某種原因未釋放或無法釋放仇冯,造成系統(tǒng)內(nèi)存的浪費(fèi),導(dǎo)致程序運(yùn)行速度減慢甚至系統(tǒng)崩潰族操。
- 靜態(tài)局部對象
在局部對象的前面加上static修飾
靜態(tài)局部對象和全局變量一樣按靜態(tài)存儲(chǔ)處理苛坚,即它的生命期與程序運(yùn)行期相同,所有靜態(tài)局部對象可以將其值一直保持到程序結(jié)束或者下次修改色难。
靜態(tài)局部對象和全局對象的區(qū)別是它的作用域是塊作用域泼舱,只能在局部區(qū)域使用。靜態(tài)局部對象在還未調(diào)用函數(shù)前甚至是程序運(yùn)行時(shí)就進(jìn)行初始化了莱预,所以每次調(diào)用時(shí)不會(huì)再有初始化操作柠掂。如果靜態(tài)局部對象定義時(shí)未賦初值,則用0填充依沮。
當(dāng)一個(gè)函數(shù)會(huì)被多次調(diào)用又希望它的某些值保持住時(shí)涯贞,就因該使用功能靜態(tài)局部對象。需要注意全局對象定義前加上static不是靜態(tài)的意思危喉,全局本身已是靜態(tài)宋渔,而是私有的意思,此時(shí)全局對象的作用域?yàn)樵撛次募?/li> - 程序組織結(jié)構(gòu)
- 內(nèi)部函數(shù)
函數(shù)本質(zhì)上是全局的辜限,在函數(shù)定義前面加上static修飾皇拣,稱其為內(nèi)部函數(shù),僅在包含它的文件中可見薄嫡。 - 外部函數(shù)
在函數(shù)定義前加上extern修飾氧急,稱其為外部函數(shù),在調(diào)用另一個(gè)文件中的函數(shù)時(shí)毫深,需要用extern聲明此函數(shù)是外部函數(shù)吩坝,C++中所有的函數(shù)本質(zhì)上都是外部函數(shù),所有extern可以省略哑蔫。