18个C/C++的基本知识点,带好小本子记录一下
1.C中static有什么作用
(1)隱藏。當(dāng)我們同時編譯多個文件時,所有未加static前綴的全局變量和函數(shù)都具有全局可見性,故使用static在不同的文件中定義同名函數(shù)和同名變量,而不必?fù)?dān)心命名沖突。
(2)static的第二個作用是保持變量內(nèi)容的持久。存儲在靜態(tài)數(shù)據(jù)區(qū)的變量會在程序剛開始運(yùn)行時就完成初始化,也是唯一的一次初始化。共有兩種變量存儲在靜態(tài)存儲區(qū):全局變量和static變量。
(3)static的第三個作用是默認(rèn)初始化為0。其實(shí)全局變量也具備這一屬性,因為全局變量也存儲在靜態(tài)數(shù)據(jù)區(qū)。在靜態(tài)數(shù)據(jù)區(qū),內(nèi)存中所有的字節(jié)默認(rèn)值都是0×00,某些時候這一特點(diǎn)可以減少程序員的工作量。
?
2.C++中const有什么用?
const修飾的內(nèi)容不可改變。定義常量只是一種使用方式而已,還有const數(shù)據(jù)成員,const參數(shù),const返回值,const成員函數(shù)等,被const修飾的東西都受到強(qiáng)制保護(hù),可以預(yù)防意外的變動,能提高程序的健壯性。
3.C與C++各自是如何定義常量的?有什么不同?
C中是使用宏#define定義, C++使用更好的const來定義。
區(qū)別:
1)const是有數(shù)據(jù)類型的常量,而宏常量沒有,編譯器可以對前者進(jìn)行靜態(tài)類型安全檢查,對后者僅是字符替換,沒有類型安全檢查,而且在字符替換時可能會產(chǎn)生意料不到的錯誤(邊際效應(yīng))。
2)有些編譯器可以對const常量進(jìn)行調(diào)試, 不能對宏調(diào)試。
既然C++中有更好的const為什么還要使用宏?
const無法代替宏作為衛(wèi)哨來防止文件的重復(fù)包含。
?
4.C++中引用和指針的區(qū)別?
引用是對象的別名,操作引用就是操作這個對象,必須在創(chuàng)建的同時有效得初始化(引用一個有效的對象,不可為NULL),初始化完畢就再也不可改變,引用具有指針的效率,又具有變量使用的方便性和直觀性,在語言層面上引用和對象的用法一樣,在二進(jìn)制層面上引用一般都是通過指針來實(shí)現(xiàn)的,只是編譯器幫我們完成了轉(zhuǎn)換。之所以使用引用是為了用適當(dāng)?shù)墓ぞ咦銮∪缙浞值氖?#xff0c;體現(xiàn)了最小特權(quán)原則。
5.C與C++的內(nèi)存分配方式?
1)從靜態(tài)存儲區(qū)域分配。內(nèi)存在程序編譯的時候就已經(jīng)分配好,這塊內(nèi)存在程序的整個運(yùn)行期間都存在,如全局變量,static變量。
2)在棧上創(chuàng)建。在執(zhí)行函數(shù)時,函數(shù)內(nèi)局部變量的存儲單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時這些存儲單元自動被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限。
3)從堆上分配(動態(tài)內(nèi)存分配)。程序在運(yùn)行的時候用malloc或new申請任意多少的內(nèi)存,程序員負(fù)責(zé)在何時用free或delete釋放內(nèi)存。動態(tài)內(nèi)存的生存期自己決定,使用非常靈活。
補(bǔ)充:棧、堆的區(qū)別
一、堆棧空間分配區(qū)別:
1、棧(操作系統(tǒng)):由操作系統(tǒng)自動分配釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧;
2、堆(操作系統(tǒng)): 一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時可能由OS回收,分配方式倒是類似于鏈表。
二、堆棧緩存方式區(qū)別:
1、棧使用的是一級緩存, 他們通常都是被調(diào)用時處于存儲空間中,調(diào)用完畢立即釋放;
2、堆是存放在二級緩存中,生命周期由虛擬機(jī)的垃圾回收算法來決定(并不是一旦成為孤兒對象就能被回收)。所以調(diào)用這些對象的速度要相對來得低一些。
三、堆棧數(shù)據(jù)結(jié)構(gòu)區(qū)別:
堆(數(shù)據(jù)結(jié)構(gòu)):堆可以被看成是一棵樹,如:堆排序;
棧(數(shù)據(jù)結(jié)構(gòu)):一種先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu)。
?
學(xué)習(xí)從來不是一個人的事情,要有個相互監(jiān)督的伙伴,工作需要學(xué)習(xí)C/C++或者有興趣學(xué)習(xí)C/C++的伙伴可以私信回復(fù)小編“學(xué)習(xí)”領(lǐng)取全套免費(fèi)C/C++學(xué)習(xí)資料、視頻
6.new/delete 與 malloc()/free() 的區(qū)別?
malloc()與 free()是C語言的標(biāo)準(zhǔn)庫函數(shù),new/delete 是C++的運(yùn)算符,他們都可以用來申請和釋放內(nèi)存,malloc()和free()不在編譯器控制權(quán)限之內(nèi),不能把構(gòu)造函數(shù)和析構(gòu)函數(shù)的任務(wù)強(qiáng)加給他們。
7. 在C++ 程序中調(diào)用被 C編譯器編譯后的函數(shù),為什么要加 extern “C”?
C++語言支持函數(shù)重載,C語言不支持函數(shù)重載。
函數(shù)被C++編譯后在庫中的名字與C語言的不同。假設(shè)某個函數(shù)的原型為: void foo(int x, int y);該函數(shù)被C編譯器編譯后在庫中的名字為_foo,而C++編譯器則會產(chǎn)生像_foo_int_int之類的名字。C++提供了C連接交換指定符號extern”C”來解決名字匹配問題。
8. C++中的什么是多態(tài)性? 是如何實(shí)現(xiàn)的?
多態(tài)性是面向?qū)ο蟪绦蛟O(shè)計語言繼封裝和繼承之后的第三個基本特征。
它是在運(yùn)行時出現(xiàn)的多態(tài)性通過派生類和虛函數(shù)實(shí)現(xiàn)。基類和派生類中使用同樣的函數(shù)名, 完成不同的操作具體實(shí)現(xiàn)相隔離的另一類接口,即把” w h a t”從”h o w”分離開來。多態(tài)性提高了代碼的組織性和可讀性,虛函數(shù)則根據(jù)類型的不同來進(jìn)行不同的隔離。
9. 什么是動態(tài)特性?
在絕大多數(shù)情況下,程序的功能是在編譯的時候就確定下來的,我們稱之為靜態(tài)特性。 反之,如果程序的功能是在運(yùn)行時刻才能確定下來的, 則稱之為動態(tài)特性。C++中,虛函數(shù),抽象基類,動態(tài)綁定和多態(tài)構(gòu)成了出色的動態(tài)特性。
10. 什么是封裝?C++中是如何實(shí)現(xiàn)的?
封裝來源于信息隱藏的設(shè)計理念,是通過特性和行為的組合來創(chuàng)建新數(shù)據(jù)類型讓接口與具體實(shí)現(xiàn)相隔離。C++中是通過類來實(shí)現(xiàn)的,為了盡量避免某個模塊的行為干擾同一系統(tǒng)中的其它模塊,應(yīng)該讓模塊僅僅公開必須讓外界知道的接口。
?
11. 拷貝構(gòu)造函數(shù) & 深淺拷貝
拷貝構(gòu)造函數(shù)是單個參數(shù)的構(gòu)造函數(shù),其參數(shù)是與它同屬一類的對象的(常)引用;類定義中,如果未提供自己的拷貝構(gòu)造函數(shù),C++提供一個默認(rèn)拷貝構(gòu)造函數(shù),該默認(rèn)拷貝構(gòu)造函數(shù)完成一個成員到一個成員的拷貝。
淺拷貝是創(chuàng)建了一個對象用一個現(xiàn)成的對象初始化它的時候只是復(fù)制了成員(簡單賦值)而沒有拷貝分配給成員的資源(如給其指針變量成員分配了動態(tài)內(nèi)存);
深拷貝是當(dāng)一個對象創(chuàng)建時,如果分配了資源,就需要定義自己的拷貝構(gòu)造函數(shù),使之不但拷貝成員也拷貝分配給它的資源。
12. 面向?qū)ο蟪绦蛟O(shè)計的優(yōu)點(diǎn)?
開發(fā)時間短, 效率高, 可靠性高。面向?qū)ο缶幊痰木幋a具有高可重用性,可以在應(yīng)用程序中大量采用成熟的類庫(如STL),從而雖短了開發(fā)時間,軟件易于維護(hù)和升級。
?
13. strcpy實(shí)現(xiàn)
需要注意下面幾點(diǎn)
(1)將源字符串加const,表明其為輸入?yún)?shù)
(2)對源地址和目的地址加非0斷言
(3)為了實(shí)現(xiàn)鏈?zhǔn)讲僮?#xff0c;將目的地址返回
char * strcpy( char *strDest, const char *strSrc ) { assert( (strDest != NULL) && (strSrc != NULL) ); char *address = strDest; while( (*strDest++ = * strSrc++) != ‘\0’); return address; }14. delete與 delete []區(qū)別
delete只會調(diào)用一次析構(gòu)函數(shù),而delete[]會調(diào)用每一個成員的析構(gòu)函數(shù)。
在More Effective C++中有更為詳細(xì)的解釋:“當(dāng)delete操作符用于數(shù)組時,它為每個數(shù)組元素調(diào)用析構(gòu)函數(shù),然后調(diào)用operator delete來釋放內(nèi)存。”delete與new配套,delete []與new []配套。
MemTest *mTest1=new MemTest[10]; MemTest *mTest2=new MemTest; Int *pInt1=new int [10]; Int *pInt2=new int; delete[]pInt1; //-1- delete[]pInt2; //-2- delete[]mTest1;//-3- delete[]mTest2;//-4-在-4-處報錯。
這就說明:對于內(nèi)建簡單數(shù)據(jù)類型,delete和delete[]功能是相同的。
對于自定義的復(fù)雜數(shù)據(jù)類型,delete和delete[]不能互用。delete[]刪除一個數(shù)組,delete刪除一個指針。
簡單來說,用new分配的內(nèi)存用delete刪除;用new[]分配的內(nèi)存用delete[]刪除。delete[]會調(diào)用數(shù)組元素的析構(gòu)函數(shù)。內(nèi)部數(shù)據(jù)類型沒有析構(gòu)函數(shù),所以問題不大。如果你在用delete時沒用括號,delete就會認(rèn)為指向的是單個對象,否則,它就會認(rèn)為指向的是一個數(shù)組。
?
15. 子類析構(gòu)時要調(diào)用父類的析構(gòu)函數(shù)嗎?
析構(gòu)函數(shù)調(diào)用的次序是先派生類的析構(gòu)后基類的析構(gòu),也就是說在基類的的析構(gòu)調(diào)用的時候,派生類的信息已經(jīng)全部銷毀了。
定義一個對象時先調(diào)用基類的構(gòu)造函數(shù)、然后調(diào)用派生類的構(gòu)造函數(shù);析構(gòu)的時候恰好相反:先調(diào)用派生類的析構(gòu)函數(shù)、然后調(diào)用基類的析構(gòu)函數(shù)。
16. 多態(tài),虛函數(shù),純虛函數(shù)
多態(tài):是對于不同對象接收相同消息時產(chǎn)生不同的動作。C++的多態(tài)性具體體現(xiàn)在運(yùn)行和編譯兩個方面:在程序運(yùn)行時的多態(tài)性通過繼承和虛函數(shù)來體現(xiàn);在程序編譯時多態(tài)性體現(xiàn)在函數(shù)和運(yùn)算符的重載上;
虛函數(shù):在基類中冠以關(guān)鍵字 virtual 的成員函數(shù)。 它提供了一種接口界面。允許在派生類中對基類的虛函數(shù)重新定義。
純虛函數(shù)的作用:在基類中為其派生類保留一個函數(shù)的名字,以便派生類根據(jù)需要對它進(jìn)行定義。作為接口而存在 純虛函數(shù)不具備函數(shù)的功能,一般不能直接被調(diào)用。
從基類繼承來的純虛函數(shù),在派生類中仍是虛函數(shù)。如果一個類中至少有一個純虛函數(shù),那么這個類被稱為抽象類(abstract class)。
抽象類中不僅包括純虛函數(shù),也可包括虛函數(shù)。抽象類必須用作派生其他類的基類,而不能用于直接創(chuàng)建對象實(shí)例。但仍可使用指向抽象類的指針支持運(yùn)行時多態(tài)性。
?
17. 重載(overload)和重寫(overried,有的書也叫做“覆蓋”)的區(qū)別?
從定義上來說:
重載:是指允許存在多個同名函數(shù),而這些函數(shù)的參數(shù)表不同(或許參數(shù)個數(shù)不同,或許參數(shù)類型不同,或許兩者都不同)。
重寫:是指子類重新定義父類虛函數(shù)的方法。
從實(shí)現(xiàn)原理上來說:
重載:編譯器根據(jù)函數(shù)不同的參數(shù)表,對同名函數(shù)的名稱做修飾,然后這些同名函數(shù)就成了不同的函數(shù)(至少對于編譯器來說是這樣的)。如,有兩個同名函數(shù):function func(p:integer):integer;和function func(p:string):integer;。那么編譯器做過修飾后的函數(shù)名稱可能是這樣的:int_func、str_func。對于這兩個函數(shù)的調(diào)用,在編譯器間就已經(jīng)確定了,是靜態(tài)的。也就是說,它們的地址在編譯期就綁定了(早綁定),因此,重載和多態(tài)無關(guān)!
重寫:和多態(tài)真正相關(guān)。當(dāng)子類重新定義了父類的虛函數(shù)后,父類指針根據(jù)賦給它的不同的子類指針,動態(tài)的調(diào)用屬于子類的該函數(shù),這樣的函數(shù)調(diào)用在編譯期間是無法確定的(調(diào)用的子類的虛函數(shù)的地址無法給出)。因此,這樣的函數(shù)地址是在運(yùn)行期綁定的(晚綁定)。
18. 引用與指針有什么區(qū)別?
1) 引用必須被初始化,指針不必。
2) 引用初始化以后不能被改變,指針可以改變所指的對象。
3) 不存在指向空值的引用,但是存在指向空值的指針。
最后如果大家對C/C++感興趣的話,可以加一下我們的學(xué)習(xí)交流Q群:637935295,免費(fèi)領(lǐng)取一套學(xué)習(xí)資料和視頻課程喲~
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的18个C/C++的基本知识点,带好小本子记录一下的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 科大星云诗社动态20210215
- 下一篇: [云炬python3玩转机器学习]5-2