C炕横、C++、數(shù)據(jù)結(jié)構(gòu)
1葡粒、編譯系統(tǒng)的四個(gè)步驟: 預(yù)處理份殿,編譯,匯編嗽交,鏈接
2卿嘲、整型和長(zhǎng)整型的區(qū)別?
早期的計(jì)算機(jī)轮纫,16編譯器, 整型是16位腔寡,長(zhǎng)整型是32位的。
從C99規(guī)定開(kāi)始掌唾,整型和長(zhǎng)整型都是32位放前,也就是我們sizeof得出的4個(gè)字節(jié)
3、for(;;)和while(1)無(wú)限循環(huán)的區(qū)別:
for(;;)在c語(yǔ)言中指令較少糯彬,也能夠節(jié)省內(nèi)存凭语,沒(méi)有判斷跳轉(zhuǎn),是比while(1)更好的無(wú)限循環(huán)
4撩扒、指針和數(shù)組的組合
int a; //整型數(shù)a
int *a; //整型指針a
int **a; //指向指針的指針似扔,a指針?lè)祷匾粋€(gè)整型
int a[10]; //數(shù)組a里有10個(gè)整型
int *a[10]; //數(shù)組a里面10個(gè) 指針,指針指向整型
int (*a)[10]; //指針a指向10個(gè)整型數(shù)組
int *a(int); //指針a指向函數(shù)搓谆,函數(shù)參數(shù)是整型炒辉,返回值是整型
int (*a[10])(int); //數(shù)組a里面10個(gè) 指針,指針指向函數(shù)泉手,函數(shù)參數(shù)是整型黔寇,返回值是整型
5、關(guān)鍵字static的作用
- 函數(shù)體內(nèi) static 變量的作用范圍為該函數(shù)體斩萌,不同于 auto 變量缝裤, 該變量的內(nèi)存只被分配一次,因此其值在下次調(diào)用時(shí)仍維持上次的值
- 在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所有函數(shù)訪問(wèn)颊郎,但不能被模塊外其他函數(shù)訪問(wèn)
- 在模塊內(nèi)的static 函數(shù)只可被這一模塊內(nèi)的其他函數(shù)調(diào)用憋飞,這個(gè)函數(shù)的使用范圍被限制在聲明它的模塊內(nèi)
- 在類的static 成員變量屬于整個(gè)類所擁有,對(duì)類的所以對(duì)象只有一份拷貝
- 在類中的 static 成員函數(shù)屬于整個(gè)類所擁有姆吭,這個(gè)函數(shù)不接收 this 指針榛做,因而只能訪問(wèn)類的 static 成員變量。
6、const的作用瘤睹?
1)可以定義const常量量升敲,具有不可變性。
2)便于進(jìn)行類型檢查轰传,使編譯器對(duì)處理內(nèi)容有更好了解,消除一些隱患瘪撇。
3)可以避免意義模糊的數(shù)字出現(xiàn)获茬,同樣可以方便進(jìn)行參數(shù)的調(diào)整和修改可以保護(hù)被修飾的東西,防止意外的修改倔既。
4)為函數(shù)重載提供一個(gè)參數(shù)恕曲。
5)可以節(jié)省空間,避免不必要的內(nèi)存分配渤涌。
6)編譯器通常不為普通的const常量分配內(nèi)存佩谣,將他保存在符號(hào)表,沒(méi)有存儲(chǔ)和讀取的操作实蓬,效率變高茸俭。
7、如果一個(gè)函數(shù)沒(méi)有顯式地聲明返回值安皱,那么默認(rèn)的返回值就是int型的
在c語(yǔ)言中调鬓,如果一個(gè)函數(shù)沒(méi)有顯式地說(shuō)明參數(shù)是void,那么是可以使用參數(shù)的進(jìn)行調(diào)用的
在C++這樣是不可以的
8酌伊、大小端問(wèn)題值得注意:跟處理器有關(guān)腾窝,可以使用程序判定
#include <iostream>
using namespace std;
union Test
{
int a;
char b;
};
int main()
{
Test t;
t.a = 1;
if (t.b == 1)
cout << "小端" << endl;
else
cout << "大端" << endl;
return 0;
}
9、enum是在編譯階段確定其值的
10居砖、const修飾的只讀變量不能用來(lái)作為定義數(shù)組的維數(shù)虹脯,也不能放在case關(guān)鍵字后面
11、strlen和sizeof的區(qū)別奏候?
1)strlen是一個(gè)函數(shù)循集,sizeof是一個(gè)運(yùn)算符。
2)sizeof獲得保證能容納實(shí)現(xiàn)所建立的最大對(duì)象的字節(jié)大小鼻由,不能用來(lái)返回動(dòng)態(tài)分配的內(nèi)存空間的大小暇榴。
3)strlen要在運(yùn)行時(shí)才能計(jì)算,參數(shù)必須是字符型指針蕉世,返回字符串的長(zhǎng)度蔼紧。
12、指針和引用的區(qū)別
1.引用是變量的一個(gè)別名狠轻,內(nèi)部實(shí)現(xiàn)是只讀指針
2.引用只能在初始化時(shí)被賦值奸例,其他時(shí)候值不能被改變,指針的值可以在任何時(shí)候被改變
3.引用不能為NULL,指針可以為NULL
4.引用變量?jī)?nèi)存單元保存的是被引用變量的地址
5.“sizeof 引用" = 指向變量的大小 查吊, "sizeof 指針"= 指針本身的大小
6.引用可以取地址操作谐区,返回的是被引用變量本身所在的內(nèi)存單元地址
7.引用使用在源代碼級(jí)相當(dāng)于普通的變量一樣使用,做函數(shù)參數(shù)時(shí)逻卖,內(nèi)部傳遞的實(shí)際是變量地址
13宋列、C++中有了malloc / free , 為什么還需要 new / delete
- malloc與free是C++/C語(yǔ)言的標(biāo)準(zhǔn)庫(kù)函數(shù),new/delete是C++的運(yùn)算符评也。它們都可用于申請(qǐng)動(dòng)態(tài)內(nèi)存和釋放內(nèi)存炼杖。
- 對(duì)于非內(nèi)部數(shù)據(jù)類型的對(duì)象而言,光用maloc/free無(wú)法滿足動(dòng)態(tài)對(duì)象的要求盗迟。對(duì)象在創(chuàng)建的同時(shí)要自動(dòng)執(zhí)行構(gòu)造函數(shù)坤邪,對(duì)象在消亡之前要自動(dòng)執(zhí)行析構(gòu)函數(shù)。由于malloc/free是庫(kù)函數(shù)而不是運(yùn)算符罚缕,不在編譯器控制權(quán)限之內(nèi)艇纺,不能夠把執(zhí)行構(gòu)造函數(shù)和析構(gòu)函數(shù)的任務(wù)強(qiáng)加于malloc/free。
- 因此C++語(yǔ)言需要一個(gè)能完成動(dòng)態(tài)內(nèi)存分配和初始化工作的運(yùn)算符new邮弹,以一個(gè)能完成清理與釋放內(nèi)存工作的運(yùn)算符delete黔衡。注意new/delete不是庫(kù)函數(shù)。
14肠鲫、堆和棧的區(qū)別
- 棧區(qū)(stack): 由編譯器自動(dòng)分配釋放 员帮,存放函數(shù)的參數(shù)值,局部變量的值等导饲,操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧捞高。
- 堆區(qū)(heap) : 一般由程序員分配釋放, 若程序員不釋放渣锦,程序結(jié)束時(shí)可能由OS回收 硝岗。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事,作方式類似于數(shù)據(jù)結(jié)構(gòu)中的鏈表袋毙。
15型檀、不調(diào)用C/C++ 的字符串庫(kù)函數(shù),編寫(xiě)strcpy
char * strcpy(char * strDest,const char * strSrc)
{
if ((strDest==NULL)||strSrc==NULL))
return NULL;
char * strDestCopy=strDest;
while ((*strDest++=*strSrc++)!='\0');
*strDest = '\0';
return strDestCopy;
}
16听盖、關(guān)鍵字static的作用
1.函數(shù)體內(nèi) static 變量的作用范圍為該函數(shù)體胀溺,不同于 auto 變量, 該變量的內(nèi)存只被分配一次皆看,因此其值在下次調(diào)用時(shí)仍維持上次的值
2.在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所有函數(shù)訪問(wèn)仓坞,但不能被模塊外其他函數(shù)訪問(wèn)
3.在模塊內(nèi)的static 函數(shù)只可被這一模塊內(nèi)的其他函數(shù)調(diào)用,這個(gè)函數(shù)的使用范圍被限制在聲明它的模塊內(nèi)
4.在類的static 成員變量屬于整個(gè)類所擁有腰吟,對(duì)類的所以對(duì)象只有一份拷貝
5.在類中的 static 成員函數(shù)屬于整個(gè)類所擁有无埃,這個(gè)函數(shù)不接收 this 指針,因而只能訪問(wèn)類的 static 成員變量
17、什么時(shí)候要用虛析構(gòu)函數(shù)
通過(guò)基類的指針來(lái)刪除派生類的對(duì)象時(shí)嫉称,基類的析構(gòu)函數(shù)應(yīng)該是虛的侦镇。否則其刪除效果將無(wú)法實(shí)現(xiàn)。一般情況下织阅,這樣的刪除只能夠刪除基類對(duì)象壳繁,而不能刪除子類對(duì)象,造成內(nèi)存泄漏荔棉。
原因:在公有繼承中氮趋,基類對(duì)派生類及其對(duì)象的操作,只能影響到那些從基類繼承下來(lái)的成員江耀。如果想要用基類對(duì)非繼承成員進(jìn)行操作,則要把基類的這個(gè)操作(函數(shù))定義為虛函數(shù)诉植。那么祥国,析構(gòu)函數(shù)自然也應(yīng)該如此:如果它想析構(gòu)子類中的重新定義或新的成員及對(duì)象,當(dāng)然也應(yīng)該聲明為虛的晾腔。
注意:如果不需要基類對(duì)派生類及對(duì)象進(jìn)行操作舌稀,則不能定義虛函數(shù)(包括虛析構(gòu)函數(shù)),因?yàn)檫@樣會(huì)增加內(nèi)存開(kāi)銷灼擂。
18壁查、C++怎樣讓返回對(duì)象的函數(shù)不調(diào)用拷貝構(gòu)造函數(shù)
拷貝構(gòu)造函數(shù)前加 “explicit” 關(guān)鍵字
19、請(qǐng)用簡(jiǎn)單的語(yǔ)言告訴我C++ 是什么剔应?
C++是在C語(yǔ)言的基礎(chǔ)上開(kāi)發(fā)的一種面向?qū)ο缶幊陶Z(yǔ)言睡腿,應(yīng)用廣泛。C++支持多種編程范式 --面向?qū)ο缶幊叹⒎盒途幊毯瓦^(guò)程化編程席怪。 其編程領(lǐng)域眾廣,常用于系統(tǒng)開(kāi)發(fā)纤控,引擎開(kāi)發(fā)等應(yīng)用領(lǐng)域挂捻。
20、C和C++的區(qū)別船万?
C++在c的基礎(chǔ)上增添類刻撒,C是一個(gè)結(jié)構(gòu)化語(yǔ)言,它的重點(diǎn)在于算法和數(shù)據(jù)結(jié)構(gòu)耿导。C程序的設(shè)計(jì)首要考慮的是如何通過(guò)一個(gè)過(guò)程声怔,對(duì)輸入(或環(huán)境條件)進(jìn)行運(yùn)算處理得到輸出(或?qū)崿F(xiàn)過(guò)程(事務(wù))控制),而對(duì)于C++碎节,首要考慮的是如何構(gòu)造一個(gè)對(duì)象模型捧搞,讓這個(gè)模型能夠契合與之對(duì)應(yīng)的問(wèn)題域,這樣就可以通過(guò)獲取對(duì)象的狀態(tài)信息得到輸出或?qū)崿F(xiàn)過(guò)程(事務(wù))控制。
21胎撇、什么是多態(tài)介粘?
多態(tài)是指相同的操作或函數(shù)、過(guò)程可作用于多種類型的對(duì)象上并獲得不同的結(jié)果晚树。不同的對(duì)象姻采,收到同一消息可以產(chǎn)生不同的結(jié)果,這種現(xiàn)象稱為多態(tài)爵憎。
22慨亲、類的static變量在什么時(shí)候初始化?函數(shù)的static變量在什么時(shí)候初始化宝鼓?
類的靜態(tài)成員變量在類實(shí)例化之前就已經(jīng)存在了刑棵,并且分配了內(nèi)存。函數(shù)的static變量在執(zhí)行此函數(shù)時(shí)進(jìn)行初始化愚铡。
23蛉签、解釋下封裝、繼承和多態(tài)沥寥?
封裝:封裝是實(shí)現(xiàn)面向?qū)ο蟪绦蛟O(shè)計(jì)的第一步碍舍,封裝就是將數(shù)據(jù)或函數(shù)等集合在一個(gè)個(gè)的單元中(我們稱之為類)。封裝的意義在于保護(hù)或者防止代碼(數(shù)據(jù))被我們無(wú)意中破壞邑雅。
繼承:繼承主要實(shí)現(xiàn)重用代碼片橡,節(jié)省開(kāi)發(fā)時(shí)間。子類可以繼承父類的一些東西淮野。
多態(tài):同一操作作用于不同的對(duì)象捧书,可以有不同的解釋,產(chǎn)生不同的執(zhí)行結(jié)果录煤。在運(yùn)行時(shí)鳄厌,可以通過(guò)指向基類的指針,來(lái)調(diào)用實(shí)現(xiàn)派生類中的方法妈踊。
24了嚎、什么是內(nèi)存泄漏?面對(duì)內(nèi)存泄漏和指針越界廊营,你有哪些方法歪泳?你通常采用哪些方法來(lái)避免和減少這類錯(cuò)誤?
用動(dòng)態(tài)存儲(chǔ)分配函數(shù)動(dòng)態(tài)開(kāi)辟的空間露筒,在使用完畢后未釋放呐伞,結(jié)果導(dǎo)致一直占據(jù)該內(nèi)存單元即為內(nèi)存泄露。
使用的時(shí)候要記得指針的長(zhǎng)度慎式。malloc的時(shí)候得確定在那里free.對(duì)指針賦值的時(shí)候應(yīng)該注意被賦值指針需要不需要釋放.動(dòng)態(tài)分配內(nèi)存的指針最好不要再次賦值.
25伶氢、常用的排序算法有哪些趟径?簡(jiǎn)單描述幾個(gè)排序算法的優(yōu)缺點(diǎn)?
選擇癣防、冒泡蜗巧、快速、希爾蕾盯、歸并幕屹、堆排等。
1.快排:是冒泡排序的一種改進(jìn)级遭。
優(yōu)點(diǎn):快望拖,數(shù)據(jù)移動(dòng)少
缺點(diǎn):穩(wěn)定性不足
2.歸并:分治法排序,穩(wěn)定的排序算法挫鸽,一般用于對(duì)總體無(wú)序说敏,但局部有序的數(shù)列。
優(yōu)點(diǎn):效率高O(n)丢郊,穩(wěn)定
缺點(diǎn):比較占用內(nèi)存
26像云、解釋C++中靜態(tài)函數(shù)和靜態(tài)變量?
- 類靜態(tài)數(shù)據(jù)成員在編譯時(shí)創(chuàng)建并初始化:在該類的任何對(duì)象建立之前就存在蚂夕,不屬于任何對(duì)象,而非靜態(tài)類成員變量則是屬于對(duì)象所有的腋逆。類靜態(tài)數(shù)據(jù)成員只有一個(gè)拷貝婿牍,為所有此類的對(duì)象所共享。
- 類靜態(tài)成員函數(shù)屬于整個(gè)類惩歉,不屬于某個(gè)對(duì)象等脂,由該類所有對(duì)象共享。
- 靜態(tài)成員函數(shù)的意義撑蚌,不在于信息共享上遥,數(shù)據(jù)溝通,而在于管理靜態(tài)數(shù)據(jù)成員争涌,完成對(duì)靜態(tài)數(shù)據(jù)成員的封裝粉楚。
- 靜態(tài)成員函數(shù)只能訪問(wèn)靜態(tài)數(shù)據(jù)成員。原因:非靜態(tài)成員函數(shù)亮垫,在調(diào)用時(shí) this指針時(shí)被當(dāng)作參數(shù)傳進(jìn)模软。而靜態(tài)成員函數(shù)屬于類,而不屬于對(duì)象饮潦,沒(méi)有 this 指針燃异。
27、
28继蜡、重載 ( overload) 和覆蓋 (override 重寫(xiě))的區(qū)別回俐?
重載:是指允許存在多個(gè)同名函數(shù)逛腿,而這些函數(shù)的參數(shù)表不同(或許參數(shù)個(gè)數(shù)不同,或許參數(shù)類型不同仅颇,或許兩者都不同)单默。
重寫(xiě):是指子類重新定義父類虛函數(shù)的方法。
29、多態(tài)的作用羞酗?
主要是兩個(gè):
- 隱藏實(shí)現(xiàn)細(xì)節(jié)琼开,使得代碼能夠模塊化;擴(kuò)展代碼模塊枚抵,實(shí)現(xiàn)代碼重用;
- 接口重用:為了類在繼承和派生的時(shí)候 明场,保證使用家族中任一類的實(shí)例的某一屬性時(shí)的正確調(diào)用 汽摹。
30、類成員函數(shù)的重載苦锨、覆蓋和遮蔽區(qū)別逼泣?
a. 成員函數(shù)被重載的特征:
( 1 )相同的范圍(在同一個(gè)類中);
( 2 )函數(shù)名字相同舟舒;
( 3 )參數(shù)不同拉庶;
( 4 ) virtual 關(guān)鍵字可有可無(wú)。
b. 覆蓋是指派生類函數(shù)覆蓋基類函數(shù)秃励,特征是:
( 1 )不同的范圍(分別位于派生類與基類)氏仗;
( 2 )函數(shù)名字相同;
( 3 )參數(shù)相同夺鲜;
( 4 )基類函數(shù)必須有 virtual 關(guān)鍵字皆尔。
c. 遮蔽是指派生類的函數(shù)屏蔽了與其同名的基類函數(shù),規(guī)則如下:
( 1 )如果派生類的函數(shù)與基類的函數(shù)同名币励,但是參數(shù)不同慷蠕。此時(shí),不論有無(wú) virtual 關(guān)鍵字食呻,基類的函數(shù)將被隱藏(注意別與重載混淆)流炕。
( 2 )如果派生類的函數(shù)與基類的函數(shù)同名,并且參數(shù)也相同仅胞,但是基類函數(shù)沒(méi)有 virtual 關(guān)鍵字浪感。此時(shí),基類的函數(shù)被隱藏(注意別與覆蓋混淆)
31饼问、什么是動(dòng)態(tài)特性?
在絕大多數(shù)情況下影兽, 程序的功能是在編譯的時(shí)候就確定下來(lái)的, 我們稱之為靜態(tài)特性莱革。 反之峻堰, 如果程序的功能是在運(yùn)行時(shí)刻才能確定下來(lái)的讹开, 則稱之為動(dòng)態(tài)特性。C++中捐名, 虛函數(shù)旦万,抽象基類, 動(dòng)態(tài)綁定和多態(tài)構(gòu)成了出色的動(dòng)態(tài)特性镶蹋。
32成艘、在C++ 程序中調(diào)用被 C 編譯器編譯后的函數(shù),為什么要加 extern “C”聲明贺归?
函數(shù)和變量被C++編譯后在符號(hào)庫(kù)中的名字與C語(yǔ)言的不同淆两,被extern “C”修飾的變量和函數(shù)是按照C語(yǔ)言方式編譯和連接的。由于編譯后的名字不同拂酣,C++程序不能直接調(diào)用C 函數(shù)秋冰。C++提供了一個(gè)C 連接交換指定符號(hào)extern“C”來(lái)解決這個(gè)問(wèn)題。
33婶熬、內(nèi)聯(lián)函數(shù)INline和宏定義一起使用的區(qū)別剑勾。
內(nèi)聯(lián)函數(shù)是在編譯的時(shí)候已經(jīng)做好將對(duì)應(yīng)的函數(shù)代碼替換嵌入到對(duì)應(yīng)的位置,適用于代碼較少的函數(shù)赵颅。 宏定義是簡(jiǎn)單的替換變量虽另,如果定義的是有參數(shù)的函數(shù)形式,參數(shù)不做類型校驗(yàn)饺谬。
34洲赵、一個(gè)空類默認(rèn)存在的成員函數(shù)有哪些?
默認(rèn)構(gòu)造函數(shù)商蕴、默認(rèn)拷貝構(gòu)造函數(shù)、默認(rèn)析構(gòu)函數(shù)芝发、默認(rèn)賦值運(yùn)算符 這四個(gè)是我們通常大都知道的绪商。但是除了這四個(gè),還有兩個(gè)辅鲸,那就是取址運(yùn)算符和 取址運(yùn)算符 const
即總共有六個(gè)函數(shù)格郁。
class Empty
{
public:
Empty(); // 缺省構(gòu)造函數(shù)
Empty( const Empty& ); // 拷貝構(gòu)造函數(shù)
~Empty(); // 析構(gòu)函數(shù)
Empty& operator=( const Empty& ); // 賦值運(yùn)算符
Empty* operator&(); // 取址運(yùn)算符
const Empty* operator&() const; // 取址運(yùn)算符 const
};
35、C++中哪些函數(shù)不能被聲明為虛函數(shù)独悴?
普通函數(shù)(非成員函數(shù))例书,構(gòu)造函數(shù),內(nèi)聯(lián)成員函數(shù)刻炒、靜態(tài)成員函數(shù)决采、友元函數(shù)。
(1)虛函數(shù)用于基類和派生類坟奥,普通函數(shù)所以不能
(2)構(gòu)造函數(shù)不能是因?yàn)樘摵瘮?shù)采用的是虛調(diào)用的方法树瞭,
(3)內(nèi)聯(lián)成員函數(shù)的實(shí)質(zhì)是在調(diào)用的地方直接將代碼擴(kuò)展開(kāi)
(4)繼承時(shí)拇厢,靜態(tài)成員函數(shù)不能被繼承的,它只屬于一個(gè)類晒喷,因?yàn)橐膊淮嬖趧?dòng)態(tài)聯(lián)編
(5)友元函數(shù)不是類的成員函數(shù)孝偎,因此也不能被繼承
36、類的靜態(tài)成員和非靜態(tài)成員有何區(qū)別凉敲?
類的靜態(tài)成員每個(gè)類只有一個(gè)衣盾,靜態(tài)成員為所有類的實(shí)例對(duì)象共享,靜態(tài)成員有靜態(tài)成員變量和靜態(tài)成員函數(shù)爷抓,靜態(tài)成員變量使用前必須初始化势决,靜態(tài)成員變量可以被靜態(tài)成員函數(shù)和非靜態(tài)成員函數(shù)訪問(wèn),而靜態(tài)成員函數(shù)只能訪問(wèn)靜態(tài)成員變量废赞,因?yàn)殪o態(tài)成員函數(shù)屬于類徽龟,其沒(méi)有this指針。非靜態(tài)成員每個(gè)對(duì)象都有一個(gè)唉地。
37据悔、繼承的優(yōu)缺點(diǎn)。
類繼承是在編譯時(shí)刻靜態(tài)定義的耘沼,且可直接使用极颓,類繼承可以較方便地改變父類的實(shí)現(xiàn)。但是類繼承也有一些不足之處群嗤。首先菠隆,因?yàn)槔^承在編譯時(shí)刻就定義了,所以無(wú)法在運(yùn)行時(shí)刻改變從父類繼承的實(shí)現(xiàn)狂秘。更糟的是骇径,父類通常至少定義了子類的部分行為,父類的任何改變都可能影響子類的行為者春。如果繼承下來(lái)的實(shí)現(xiàn)不適合解決新的問(wèn)題破衔,則父類必須重寫(xiě)或被其他更適合的類替換。這種依賴關(guān)系限制了靈活性并最終限制了復(fù)用性钱烟。
38晰筛、在什么時(shí)候需要使用“常引用”?
如果既要利用引用提高程序的效率拴袭,又要保護(hù)傳遞給函數(shù)的數(shù)據(jù)不在函數(shù)中被改變读第,就 應(yīng)使用常引用。常引用聲明方式:const 類型標(biāo)識(shí)符 &引用名=目標(biāo)變量名拥刻;
39怜瞒、什么是淺拷貝?什么是深拷貝般哼?
淺拷貝是指源對(duì)象與拷貝對(duì)象共用一份實(shí)體盼砍,僅僅是引用的變量不同(名稱不同)尘吗。對(duì)其中任何一個(gè)對(duì)象的改動(dòng)都會(huì)影響另外一個(gè)對(duì)象。
深拷貝是指源對(duì)象與拷貝對(duì)象互相獨(dú)立浇坐,其中任何一個(gè)對(duì)象的改動(dòng)都不會(huì)對(duì)另外一個(gè)對(duì)象造成影響睬捶。
一般來(lái)說(shuō),淺拷貝就是復(fù)制那個(gè)對(duì)象的指針近刘。深拷貝就是復(fù)制了那個(gè)對(duì)象擒贸。
40、簡(jiǎn)述多態(tài)實(shí)現(xiàn)的原理
編譯器發(fā)現(xiàn)一個(gè)類中有虛函數(shù)觉渴,便會(huì)立即為此類生成虛函數(shù)表 vtable介劫。虛函數(shù)表的各表項(xiàng)為指向?qū)?yīng)虛函數(shù)的指針。編譯器還會(huì)在此類中隱含插入一個(gè)指針vptr(對(duì)vc編譯器來(lái)說(shuō)案淋,它插在類的第一個(gè)位置上)指向虛函數(shù)表座韵。調(diào)用此類的構(gòu)造函數(shù)時(shí),在類的構(gòu)造函數(shù)中踢京,編譯器會(huì)隱含執(zhí)行vptr與vtable的關(guān)聯(lián)代碼誉碴,將vptr指向?qū)?yīng)的vtable,將類與此類的vtable聯(lián)系了起來(lái)瓣距。另外在調(diào)用類的構(gòu)造函數(shù)時(shí)黔帕,指向基礎(chǔ)類的指針此時(shí)已經(jīng)變成指向具體的類的this指針,這樣依靠此this指針即可得到正確的vtable蹈丸,成黄。如此才能真正與函數(shù)體進(jìn)行連接,這就是動(dòng)態(tài)聯(lián)編逻杖,實(shí)現(xiàn)多態(tài)的基本原理奋岁。
41、談?wù)勀銓?duì)面向?qū)ο蟮恼J(rèn)識(shí)
解析:面向?qū)ο罂梢岳斫獬蓪?duì)待每一個(gè)問(wèn)題荸百,都是首先要確定這個(gè)問(wèn)題由幾個(gè)部分組成闻伶,而每一個(gè)部分其實(shí)就是一個(gè)對(duì)象。然后再分別設(shè)計(jì)這些對(duì)象管搪,最后得到整個(gè)程序。傳統(tǒng)的程序設(shè)計(jì)多是基于功能的思想來(lái)進(jìn)行考慮和設(shè)計(jì)的铡买,而面向?qū)ο蟮某绦蛟O(shè)計(jì)則是基于對(duì)象的角度來(lái)考慮問(wèn)題更鲁。這樣做能夠使得程序更加的簡(jiǎn)潔清晰。
42奇钞、C++中為什么用模板類澡为。
- 可用來(lái)創(chuàng)建動(dòng)態(tài)增長(zhǎng)和減小的數(shù)據(jù)結(jié)構(gòu)
- 它是類型無(wú)關(guān)的,因此具有很高的可復(fù)用性景埃。
- 它在編譯時(shí)而不是運(yùn)行時(shí)檢查數(shù)據(jù)類型媒至,保證了類型安全
- 它是平臺(tái)無(wú)關(guān)的顶别,可移植性
- 可用于基本數(shù)據(jù)類型
43 、函數(shù)模板與類模板有什么區(qū)別拒啰?
函數(shù)模板的實(shí)例化是由編譯程序在處理函數(shù)調(diào)用時(shí)自動(dòng)完成的驯绎,而類模板的實(shí)例化
必須由程序員在程序中顯式地指定。
44谋旦、C++是不是類型安全的剩失?
不是。兩個(gè)不同類型的指針之間可以強(qiáng)制轉(zhuǎn)換
45册着、流操作符重載為什么返回引用
在程序中拴孤,流操作符>>和<<經(jīng)常連續(xù)使用。因此這兩個(gè)操作符的返回值應(yīng)該是一個(gè)仍舊支持這兩個(gè)操作符的流引用甲捏。其他的數(shù)據(jù)類型都無(wú)法做到這一點(diǎn)演熟。
注意:除了在賦值操作符和流操作符之外的其他的一些操作符中,如+司顿、-芒粹、*、/等卻千萬(wàn)不能返回引用免猾。因?yàn)檫@四個(gè)操作符的對(duì)象都是右值是辕,因此,它們必須構(gòu)造一個(gè)對(duì)象作為返回值猎提。
46获三、多態(tài), 虛函數(shù)锨苏, 純虛函數(shù)
多態(tài):不同對(duì)象接收相同的消息產(chǎn)生不同的動(dòng)作疙教。多態(tài)包括 編譯時(shí)多態(tài)和 運(yùn)行時(shí)多態(tài)
運(yùn)行時(shí)多態(tài)是:通過(guò)繼承和虛函數(shù)來(lái)體現(xiàn)的。 編譯時(shí)多態(tài):運(yùn)算符重載上伞租。
虛函數(shù): 在基類中用virtual的成員函數(shù)贞谓。允許在派生類中對(duì)基類的虛函數(shù)重新定義。 基類的虛函數(shù)可以有函數(shù)體葵诈,基類也可以實(shí)例化裸弦。 虛函數(shù)要有函數(shù)體,否則編譯過(guò)不去作喘。 虛函數(shù)在子類中可以不覆蓋理疙。 構(gòu)造函數(shù)不能是虛函數(shù)。
純虛函數(shù):基類中為其派生類保留一個(gè)名字泞坦,以便派生類根據(jù)需要進(jìn)行定義窖贤。 包含一個(gè)純虛函數(shù)的類是抽象類。 純虛函數(shù)后面有 = 0; 抽象類不可以實(shí)例化赃梧。但可以定義指針滤蝠。 如果派生類如果不是先基類的純虛函數(shù),則仍然是抽象類授嘀。 抽象類可以包含虛函數(shù)物咳。
47、抽象類和接口的區(qū)別
在C++里面抽象類就是接口
抽象類:定義了純虛函數(shù)的類是抽象類粤攒,不能實(shí)例化所森。
抽象類包括抽象方法(純虛方法),也可以包含普通方法夯接。 抽象類可以派生自一個(gè)抽象類焕济,可以覆蓋基類的抽象方法也可以不覆蓋。
雖不能定義抽象類的實(shí)例盔几,但是可以定義抽象類的指針晴弃。
48、將引用作為函數(shù)參數(shù)有哪些特點(diǎn)
(1)與指針調(diào)用效果一樣逊拍。
(2)引用傳參上鞠,內(nèi)存中并沒(méi)有產(chǎn)生副本。
(3)用指針傳遞芯丧,也要給形參分配存儲(chǔ)單元芍阎;并且需要使用"*變量的"的形式,可讀性差缨恒;另外谴咸,調(diào)用的地方還得用地址作為實(shí)參。
49骗露、引用作為函數(shù)返回值類型的格式岭佳,好處和規(guī)則?
int &fun(int a) {}
好處:不會(huì)生成副本萧锉。
規(guī)則:不能返回局部變量的引用珊随;不能返回函數(shù)內(nèi)部new分配的內(nèi)存引用;如果返回成員的話,返回const
50、結(jié)構(gòu)與聯(lián)合的區(qū)別
聯(lián)合是公用存儲(chǔ)單元的柿隙,任何一個(gè)時(shí)刻只有一個(gè)被選中的成員叶洞。一旦賦值后,其他成員也覆蓋了禀崖。
51衩辟、重載(overload)和重寫(xiě)(override)?
重載:多個(gè)同名函數(shù),參數(shù)不同(個(gè)數(shù)不同帆焕,參數(shù)類型不同)惭婿;是同一層級(jí)的函數(shù);靜態(tài)綁定叶雹;編譯期綁定财饥。
重寫(xiě):子類重新定義父類函數(shù)的方法;是動(dòng)態(tài)綁定折晦。
52钥星、main函數(shù)之前會(huì)執(zhí)行什么代碼?
全局變量的初始化满着。
53谦炒、const 與 #define相比優(yōu)點(diǎn)?
const: 定義常量风喇; 修飾函數(shù)參數(shù)宁改; 修飾函數(shù)返回值; 修飾類成員函數(shù)魂莫。
好處: const 修飾的有數(shù)據(jù)類型还蹲,而宏沒(méi)有,所以可以做類型檢查耙考;而宏僅作字符替換谜喊,無(wú)安全檢查。
const常量可以調(diào)試
宏有副作用倦始,不加括號(hào)的話有副作用斗遏。
54、為什么基類的析構(gòu)函數(shù)是虛函數(shù)鞋邑?
動(dòng)態(tài)綁定诵次,不會(huì)造成潛在的內(nèi)存泄漏
55、子類不能繼承父類的函數(shù)有哪些
子類繼承父類大部分的資源炫狱,不能繼承的有構(gòu)造函數(shù)藻懒,析構(gòu)函數(shù),拷貝構(gòu)造函數(shù)视译,operator=函數(shù)嬉荆,友元函數(shù)。
56酷含、虛函數(shù) VS 純虛函數(shù)
虛函數(shù)為了重載和多態(tài)鄙早,在基類中是有定義的,即便定義為空椅亚。在子類中可以重寫(xiě)限番。
純虛函數(shù)在基類中沒(méi)有定義,必須在子類中實(shí)現(xiàn)呀舔。
多態(tài)的基礎(chǔ)是繼承弥虐,需要虛函數(shù)的支持扩灯。
57、開(kāi)發(fā)中常用的數(shù)據(jù)結(jié)構(gòu):
A:數(shù)組和鏈表:
數(shù)組大小不能動(dòng)態(tài)定義霜瘪。鏈表和動(dòng)態(tài)分配大小的珠插。
數(shù)組不適應(yīng)動(dòng)態(tài)增/減的情況,因?yàn)榇笮」潭ㄓ倍裕坏┒x就不能改變捻撑。
鏈表適合動(dòng)態(tài)的增加、刪除數(shù)據(jù)缤底。
數(shù)組的隨機(jī)訪問(wèn)快顾患。
數(shù)組棧中分配; 鏈表在堆中个唧。
B:二叉樹(shù)遍歷: 先序江解、中序、后序徙歼。
58膘流、棧溢出的原因:
棧大小有限制:分過(guò)多的數(shù)組;
遞歸調(diào)用層太深鲁沥;
59呼股、頻繁出現(xiàn)的短小的函數(shù),在c/C++中分別如何實(shí)現(xiàn)
c中用宏定義画恰; C++ 內(nèi)聯(lián)
60彭谁、 C++函數(shù)傳參數(shù)方式
值傳遞、指針允扇、引用
61缠局、 .h頭文件中的ifndef/define/endif作用
防止頭文件重復(fù)包含
62、什么是平衡二叉樹(shù)考润?
左右子樹(shù)都是平衡二叉樹(shù) 且左右子樹(shù)的深度差值的絕對(duì)值不大于 1 狭园。
63、用兩個(gè)棧實(shí)現(xiàn)一個(gè)隊(duì)列的功能糊治?要求給出算法和思路唱矛!
設(shè) 2 個(gè)棧為 A,B, 一開(kāi)始均為空 .
入隊(duì) :
將新元素 push 入棧 A;
出隊(duì) :
(1) 判斷棧 B 是否為空;
(2) 如果不為空井辜,則將棧 A 中所有元素依次 pop 出并 push 到棧 B 绎谦;
(3) 將棧 B 的棧頂元素 pop 出;
這樣實(shí)現(xiàn)的隊(duì)列入隊(duì)和出隊(duì)的平攤復(fù)雜度都還是 O(1)
64粥脚、關(guān)鍵字 static 的作用是什么窃肠?
在 C 語(yǔ)言中,關(guān)鍵字 static 有三個(gè)明顯的作用:
- 在函數(shù)體刷允,一個(gè)被聲明為靜態(tài)的變量在這一函數(shù)被調(diào)用過(guò)程中維持其值不變冤留。
- 在模塊內(nèi)(但在函數(shù)體外)碧囊,一個(gè)被聲明為靜態(tài)的變量可以被模塊內(nèi)所用函數(shù)訪問(wèn),但不能被模塊外其它函數(shù)訪問(wèn)纤怒。它是一個(gè)本地的全局變量呕臂。
- 在模塊內(nèi),一個(gè)被聲明為靜態(tài)的函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用肪跋。那就是,這個(gè)函數(shù)被限制在聲明它的模塊的本地范圍內(nèi)使用土砂。
65州既、什么是預(yù)編譯 , 何時(shí)需要預(yù)編譯 ?
預(yù)編譯又稱為預(yù)處理 , 是做些代碼文本的替換工作。處理 # 開(kāi)頭的指令 , 比如拷貝 #include 包含的文件代碼萝映, #define 宏定義的替換 , 條件編譯等吴叶,就是為編譯做的預(yù)備工作的階段,主要處理 # 開(kāi)始的預(yù)編譯指令序臂,預(yù)編譯指令指示了在程序正式編譯前就由編譯器進(jìn)行的操作蚌卤,可以放在程序中的任何位置。
66奥秆、Itearator 各指針的區(qū)別
游標(biāo)是指針逊彭,但不僅僅是指針。游標(biāo)和指針很像构订,功能很像指針侮叮,但是實(shí)際上,游標(biāo)是通過(guò)重載一元的 ”*” 和 ”->” 來(lái)從容器中間接地返回一個(gè)值悼瘾。將這些值存儲(chǔ)在容器中并不是一個(gè)好主意囊榜,因?yàn)槊慨?dāng)一個(gè)新值添加到容器中或者有一個(gè)值從容器中刪除,這些值就會(huì)失效亥宿。在某種程度上卸勺,游標(biāo)可以看作是句柄( handle )。通常情況下游標(biāo)( iterator )的類型可以有所變化烫扼,這樣容器也會(huì)有幾種不同方式的轉(zhuǎn)變: iterator——對(duì)于除了 vector 以外的其他任何容器曙求,你可以通過(guò)這種游標(biāo)在一次操作中在容器中朝向前的方向走一步。這意味著對(duì)于這種游標(biāo)你只能使用 “++” 操作符映企。而不能使用 “--” 或 “+=” 操作符圆到。而對(duì)于 vector 這一種容器,你可以使用 “+=” 卑吭、 “—” 芽淡、 “++” 、 “-=” 中的任何一種操作符和 “<” 豆赏、 “<=” 挣菲、 “>” 富稻、 “>=” 、 “==” 白胀、 “!=” 等比較運(yùn)算符椭赋。
67、數(shù)組和鏈表的優(yōu)缺點(diǎn)
數(shù)組或杠,在內(nèi)存上給出了連續(xù)的空間哪怔。鏈表,內(nèi)存地址上可以是不連續(xù)的向抢,每個(gè)鏈表的節(jié)點(diǎn)包括原來(lái)的內(nèi)存和下一個(gè)節(jié)點(diǎn)的信息(單向的一個(gè)认境,雙向鏈表的話,會(huì)有兩個(gè))挟鸠。
數(shù)組優(yōu)于鏈表的:
A. 內(nèi)存空間占用的少叉信。
B. 數(shù)組內(nèi)的數(shù)據(jù)可隨機(jī)訪問(wèn),但鏈表不具備隨機(jī)訪問(wèn)性艘希。
C. 查找速度快
鏈表優(yōu)于數(shù)組的:
A. 插入與刪除的操作方便硼身。
B. 內(nèi)存地址的利用率方面鏈表好。
C. 方便內(nèi)存地址擴(kuò)展覆享。
Linux部分
1佳遂、TCP和UDP有什么區(qū)別
TCP---傳輸控制協(xié)議,提供的是面向連接、可靠的字節(jié)流服務(wù)撒顿。當(dāng)客戶和服務(wù)器彼此交換數(shù)據(jù)前讶迁,必須先在雙方之間建立一個(gè)TCP連接,之后才能傳輸數(shù)據(jù)核蘸。TCP提供超時(shí)重發(fā)巍糯,丟棄重復(fù)數(shù)據(jù),檢驗(yàn)數(shù)據(jù)客扎,流量控制等功能祟峦,保證數(shù)據(jù)能從一端傳到另一端。
UDP---用戶數(shù)據(jù)報(bào)協(xié)議徙鱼,是一個(gè)簡(jiǎn)單的面向數(shù)據(jù)報(bào)的運(yùn)輸層協(xié)議宅楞。
UDP不提供可靠性,它只是把應(yīng)用程序傳給IP層的數(shù)據(jù)報(bào)發(fā)送出去袱吆,但是并不能保證它們能到達(dá)目的地厌衙。由于UDP在傳輸數(shù)據(jù)報(bào)前不用在客戶和服務(wù)器之間建立一個(gè)連接,且沒(méi)有超時(shí)重發(fā)等機(jī)制绞绒,故而傳輸速度很快
2婶希、編寫(xiě)socket套接字的步驟
服務(wù)器:建立套接字、綁定蓬衡、監(jiān)聽(tīng)喻杈、接收連接彤枢、讀寫(xiě)數(shù)據(jù)、關(guān)閉連接
客戶端:建立套接字筒饰、連接缴啡、讀寫(xiě)數(shù)據(jù)、關(guān)閉連接
3瓷们、同步IO和異步IO的區(qū)別业栅?
A. 同步
所謂同步,就是在發(fā)出一個(gè)功能調(diào)用時(shí)谬晕,在沒(méi)有得到結(jié)果之前碘裕,該調(diào)用就不返回。
按照這個(gè)定義固蚤,其實(shí)絕大多數(shù)函數(shù)都是同步調(diào)用(例如sin isdigit等)。
但是一般而言歹茶,我們?cè)谡f(shuō)同步夕玩、異步的時(shí)候,特指那些需要其他部件協(xié)作或者需要一定時(shí)間完成的任務(wù)惊豺。
最常見(jiàn)的例子就是 SendMessage燎孟。
該函數(shù)發(fā)送一個(gè)消息給某個(gè)窗口,在對(duì)方處理完消息之前尸昧,這個(gè)函數(shù)不返回揩页。
當(dāng)對(duì)方處理完畢以后,該函數(shù)才把消息處理函數(shù)所返回的值返回給調(diào)用者烹俗。
B. 異步
異步的概念和同步相對(duì)爆侣。
當(dāng)一個(gè)異步過(guò)程調(diào)用發(fā)出后,調(diào)用者不會(huì)立刻得到結(jié)果幢妄。
實(shí)際處理這個(gè)調(diào)用的部件是在調(diào)用發(fā)出后兔仰,通過(guò)狀態(tài)、通知來(lái)通知調(diào)用者蕉鸳,或通過(guò)回調(diào)函數(shù)處理這個(gè)調(diào)用乎赴。
4、進(jìn)程間通信的方式有?
進(jìn)程間通信的方式有 :共享內(nèi)存潮尝, 管道(有名管道/無(wú)名管道)榕吼,Socket ,消息隊(duì)列 勉失,信號(hào)羹蚣,信號(hào)量,內(nèi)存映射等乱凿。
5度宦、死鎖的四個(gè)必要條件踢匣?
互斥,請(qǐng)求保持戈抄,不可剝奪离唬,環(huán)路。
6划鸽、進(jìn)程和線程的差別输莺。
線程是指進(jìn)程內(nèi)的一個(gè)執(zhí)行單元,也是進(jìn)程內(nèi)的可調(diào)度實(shí)體.與進(jìn)程的區(qū)別:
(1)調(diào)度:線程作為調(diào)度和分配的基本單位,進(jìn)程作為擁有資源的基本單位
(2)并發(fā)性:不僅進(jìn)程之間可以并發(fā)執(zhí)行裸诽,同一個(gè)進(jìn)程的多個(gè)線程之間也可并發(fā)執(zhí)行
(3)擁有資源:進(jìn)程是擁有資源的一個(gè)獨(dú)立單位嫂用,線程不擁有系統(tǒng)資源,但可以訪問(wèn)隸屬于進(jìn)程的資源.
(4)系統(tǒng)開(kāi)銷:在創(chuàng)建或撤消進(jìn)程時(shí)丈冬,由于系統(tǒng)都要為之分配和回收資源嘱函,導(dǎo)致系統(tǒng)的開(kāi)銷明顯大于創(chuàng)建或撤消線程時(shí)的開(kāi)銷。
7埂蕊、多線程如何同步
windows線程同步有四種方式:臨界區(qū)往弓、內(nèi)核對(duì)象、互斥量蓄氧、信號(hào)量函似。
Linux線程同步有最常用的是:互斥鎖、條件變量和信號(hào)量喉童。