C、C++、數(shù)據(jù)結(jié)構(gòu)、Linux面試匯總(不間斷更新)

C、C++、數(shù)據(jù)結(jié)構(gòu)

1、編譯系統(tǒng)的四個步驟: 預(yù)處理,編譯,匯編,鏈接

2、整型和長整型的區(qū)別?

早期的計算機(jī),16編譯器, 整型是16位,長整型是32位的。

從C99規(guī)定開始,整型和長整型都是32位,也就是我們sizeof得出的4個字節(jié)

3、for(;;)和while(1)無限循環(huán)的區(qū)別:

for(;;)在c語言中指令較少,也能夠節(jié)省內(nèi)存,沒有判斷跳轉(zhuǎn),是比while(1)更好的無限循環(huán)

4、指針和數(shù)組的組合

int a; //整型數(shù)a
int *a; //整型指針a
int **a; //指向指針的指針,a指針返回一個整型
int a[10]; //數(shù)組a里有10個整型
int *a[10]; //數(shù)組a里面10個 指針,指針指向整型
int (*a)[10];  //指針a指向10個整型數(shù)組
int *a(int);    //指針a指向函數(shù),函數(shù)參數(shù)是整型,返回值是整型
int (*a[10])(int);   //數(shù)組a里面10個 指針,指針指向函數(shù),函數(shù)參數(shù)是整型,返回值是整型

5、關(guān)鍵字static的作用

  1. 函數(shù)體內(nèi) static 變量的作用范圍為該函數(shù)體,不同于 auto 變量, 該變量的內(nèi)存只被分配一次,因此其值在下次調(diào)用時仍維持上次的值
  2. 在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所有函數(shù)訪問,但不能被模塊外其他函數(shù)訪問
  3. 在模塊內(nèi)的static 函數(shù)只可被這一模塊內(nèi)的其他函數(shù)調(diào)用,這個函數(shù)的使用范圍被限制在聲明它的模塊內(nèi)
  4. 在類的static 成員變量屬于整個類所擁有,對類的所以對象只有一份拷貝
  5. 在類中的 static 成員函數(shù)屬于整個類所擁有,這個函數(shù)不接收 this 指針,因而只能訪問類的 static 成員變量。

6、const的作用?
1)可以定義const常量量,具有不可變性。
2)便于進(jìn)行類型檢查,使編譯器對處理內(nèi)容有更好了解,消除一些隱患。
3)可以避免意義模糊的數(shù)字出現(xiàn),同樣可以方便進(jìn)行參數(shù)的調(diào)整和修改可以保護(hù)被修飾的東西,防止意外的修改。
4)為函數(shù)重載提供一個參數(shù)。
5)可以節(jié)省空間,避免不必要的內(nèi)存分配。
6)編譯器通常不為普通的const常量分配內(nèi)存,將他保存在符號表,沒有存儲和讀取的操作,效率變高。

7、如果一個函數(shù)沒有顯式地聲明返回值,那么默認(rèn)的返回值就是int型的
在c語言中,如果一個函數(shù)沒有顯式地說明參數(shù)是void,那么是可以使用參數(shù)的進(jìn)行調(diào)用的
在C++這樣是不可以的

8、大小端問題值得注意:跟處理器有關(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修飾的只讀變量不能用來作為定義數(shù)組的維數(shù),也不能放在case關(guān)鍵字后面

11、strlen和sizeof的區(qū)別?
1)strlen是一個函數(shù),sizeof是一個運算符。
2)sizeof獲得保證能容納實現(xiàn)所建立的最大對象的字節(jié)大小,不能用來返回動態(tài)分配的內(nèi)存空間的大小。
3)strlen要在運行時才能計算,參數(shù)必須是字符型指針,返回字符串的長度。

12、指針和引用的區(qū)別
1.引用是變量的一個別名,內(nèi)部實現(xiàn)是只讀指針
2.引用只能在初始化時被賦值,其他時候值不能被改變,指針的值可以在任何時候被改變
3.引用不能為NULL,指針可以為NULL
4.引用變量內(nèi)存單元保存的是被引用變量的地址
5.“sizeof 引用" = 指向變量的大小 , "sizeof 指針"= 指針本身的大小
6.引用可以取地址操作,返回的是被引用變量本身所在的內(nèi)存單元地址
7.引用使用在源代碼級相當(dāng)于普通的變量一樣使用,做函數(shù)參數(shù)時,內(nèi)部傳遞的實際是變量地址

13、C++中有了malloc / free , 為什么還需要 new / delete

  1. malloc與free是C++/C語言的標(biāo)準(zhǔn)庫函數(shù),new/delete是C++的運算符。它們都可用于申請動態(tài)內(nèi)存和釋放內(nèi)存。
  2. 對于非內(nèi)部數(shù)據(jù)類型的對象而言,光用maloc/free無法滿足動態(tài)對象的要求。對象在創(chuàng)建的同時要自動執(zhí)行構(gòu)造函數(shù),對象在消亡之前要自動執(zhí)行析構(gòu)函數(shù)。由于malloc/free是庫函數(shù)而不是運算符,不在編譯器控制權(quán)限之內(nèi),不能夠把執(zhí)行構(gòu)造函數(shù)和析構(gòu)函數(shù)的任務(wù)強(qiáng)加于malloc/free。
  3. 因此C++語言需要一個能完成動態(tài)內(nèi)存分配和初始化工作的運算符new,以一個能完成清理與釋放內(nèi)存工作的運算符delete。注意new/delete不是庫函數(shù)。

14、堆和棧的區(qū)別

  1. 棧區(qū)(stack): 由編譯器自動分配釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等,操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。
  2. 堆區(qū)(heap) : 一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時可能由OS回收 。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事,作方式類似于數(shù)據(jù)結(jié)構(gòu)中的鏈表。

15、不調(diào)用C/C++ 的字符串庫函數(shù),編寫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)用時仍維持上次的值
2.在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所有函數(shù)訪問,但不能被模塊外其他函數(shù)訪問
3.在模塊內(nèi)的static 函數(shù)只可被這一模塊內(nèi)的其他函數(shù)調(diào)用,這個函數(shù)的使用范圍被限制在聲明它的模塊內(nèi)
4.在類的static 成員變量屬于整個類所擁有,對類的所以對象只有一份拷貝
5.在類中的 static 成員函數(shù)屬于整個類所擁有,這個函數(shù)不接收 this 指針,因而只能訪問類的 static 成員變量

17、什么時候要用虛析構(gòu)函數(shù)
通過基類的指針來刪除派生類的對象時,基類的析構(gòu)函數(shù)應(yīng)該是虛的。否則其刪除效果將無法實現(xiàn)。一般情況下,這樣的刪除只能夠刪除基類對象,而不能刪除子類對象,造成內(nèi)存泄漏。
原因:在公有繼承中,基類對派生類及其對象的操作,只能影響到那些從基類繼承下來的成員。如果想要用基類對非繼承成員進(jìn)行操作,則要把基類的這個操作(函數(shù))定義為虛函數(shù)。那么,析構(gòu)函數(shù)自然也應(yīng)該如此:如果它想析構(gòu)子類中的重新定義或新的成員及對象,當(dāng)然也應(yīng)該聲明為虛的。
注意:如果不需要基類對派生類及對象進(jìn)行操作,則不能定義虛函數(shù)(包括虛析構(gòu)函數(shù)),因為這樣會增加內(nèi)存開銷。

18、C++怎樣讓返回對象的函數(shù)不調(diào)用拷貝構(gòu)造函數(shù)
拷貝構(gòu)造函數(shù)前加 “explicit” 關(guān)鍵字

19、請用簡單的語言告訴我C++ 是什么?
C++是在C語言的基礎(chǔ)上開發(fā)的一種面向?qū)ο缶幊陶Z言,應(yīng)用廣泛。C++支持多種編程范式 --面向?qū)ο缶幊獭⒎盒途幊毯瓦^程化編程。 其編程領(lǐng)域眾廣,常用于系統(tǒng)開發(fā),引擎開發(fā)等應(yīng)用領(lǐng)域。

20、C和C++的區(qū)別?
C++在c的基礎(chǔ)上增添類,C是一個結(jié)構(gòu)化語言,它的重點在于算法和數(shù)據(jù)結(jié)構(gòu)。C程序的設(shè)計首要考慮的是如何通過一個過程,對輸入(或環(huán)境條件)進(jìn)行運算處理得到輸出(或?qū)崿F(xiàn)過程(事務(wù))控制),而對于C++,首要考慮的是如何構(gòu)造一個對象模型,讓這個模型能夠契合與之對應(yīng)的問題域,這樣就可以通過獲取對象的狀態(tài)信息得到輸出或?qū)崿F(xiàn)過程(事務(wù))控制。

21、什么是多態(tài)?
多態(tài)是指相同的操作或函數(shù)、過程可作用于多種類型的對象上并獲得不同的結(jié)果。不同的對象,收到同一消息可以產(chǎn)生不同的結(jié)果,這種現(xiàn)象稱為多態(tài)。

22、類的static變量在什么時候初始化?函數(shù)的static變量在什么時候初始化?
類的靜態(tài)成員變量在類實例化之前就已經(jīng)存在了,并且分配了內(nèi)存。函數(shù)的static變量在執(zhí)行此函數(shù)時進(jìn)行初始化。

23、解釋下封裝、繼承和多態(tài)?
封裝:封裝是實現(xiàn)面向?qū)ο蟪绦蛟O(shè)計的第一步,封裝就是將數(shù)據(jù)或函數(shù)等集合在一個個的單元中(我們稱之為類)。封裝的意義在于保護(hù)或者防止代碼(數(shù)據(jù))被我們無意中破壞。
繼承:繼承主要實現(xiàn)重用代碼,節(jié)省開發(fā)時間。子類可以繼承父類的一些東西。
多態(tài):同一操作作用于不同的對象,可以有不同的解釋,產(chǎn)生不同的執(zhí)行結(jié)果。在運行時,可以通過指向基類的指針,來調(diào)用實現(xiàn)派生類中的方法。

24、什么是內(nèi)存泄漏?面對內(nèi)存泄漏和指針越界,你有哪些方法?你通常采用哪些方法來避免和減少這類錯誤?
用動態(tài)存儲分配函數(shù)動態(tài)開辟的空間,在使用完畢后未釋放,結(jié)果導(dǎo)致一直占據(jù)該內(nèi)存單元即為內(nèi)存泄露。
使用的時候要記得指針的長度。malloc的時候得確定在那里free.對指針賦值的時候應(yīng)該注意被賦值指針需要不需要釋放.動態(tài)分配內(nèi)存的指針最好不要再次賦值.

25、常用的排序算法有哪些?簡單描述幾個排序算法的優(yōu)缺點?
選擇、冒泡、快速、希爾、歸并、堆排等。
1.快排:是冒泡排序的一種改進(jìn)。
優(yōu)點:快,數(shù)據(jù)移動少
缺點:穩(wěn)定性不足
2.歸并:分治法排序,穩(wěn)定的排序算法,一般用于對總體無序,但局部有序的數(shù)列。
優(yōu)點:效率高O(n),穩(wěn)定
缺點:比較占用內(nèi)存

26、解釋C++中靜態(tài)函數(shù)和靜態(tài)變量?

  1. 類靜態(tài)數(shù)據(jù)成員在編譯時創(chuàng)建并初始化:在該類的任何對象建立之前就存在,不屬于任何對象,而非靜態(tài)類成員變量則是屬于對象所有的。類靜態(tài)數(shù)據(jù)成員只有一個拷貝,為所有此類的對象所共享。
  2. 類靜態(tài)成員函數(shù)屬于整個類,不屬于某個對象,由該類所有對象共享。
  3. 靜態(tài)成員函數(shù)的意義,不在于信息共享,數(shù)據(jù)溝通,而在于管理靜態(tài)數(shù)據(jù)成員,完成對靜態(tài)數(shù)據(jù)成員的封裝。
  4. 靜態(tài)成員函數(shù)只能訪問靜態(tài)數(shù)據(jù)成員。原因:非靜態(tài)成員函數(shù),在調(diào)用時 this指針時被當(dāng)作參數(shù)傳進(jìn)。而靜態(tài)成員函數(shù)屬于類,而不屬于對象,沒有 this 指針。

27、


image.png

28、重載 ( overload) 和覆蓋 (override 重寫)的區(qū)別?
重載:是指允許存在多個同名函數(shù),而這些函數(shù)的參數(shù)表不同(或許參數(shù)個數(shù)不同,或許參數(shù)類型不同,或許兩者都不同)。
重寫:是指子類重新定義父類虛函數(shù)的方法。

29、多態(tài)的作用?
主要是兩個:

  1. 隱藏實現(xiàn)細(xì)節(jié),使得代碼能夠模塊化;擴(kuò)展代碼模塊,實現(xiàn)代碼重用;
  2. 接口重用:為了類在繼承和派生的時候 ,保證使用家族中任一類的實例的某一屬性時的正確調(diào)用 。

30、類成員函數(shù)的重載、覆蓋和遮蔽區(qū)別?
a. 成員函數(shù)被重載的特征:
( 1 )相同的范圍(在同一個類中);
( 2 )函數(shù)名字相同;
( 3 )參數(shù)不同;
( 4 ) virtual 關(guān)鍵字可有可無。
b. 覆蓋是指派生類函數(shù)覆蓋基類函數(shù),特征是:
( 1 )不同的范圍(分別位于派生類與基類);
( 2 )函數(shù)名字相同;
( 3 )參數(shù)相同;
( 4 )基類函數(shù)必須有 virtual 關(guān)鍵字。
c. 遮蔽是指派生類的函數(shù)屏蔽了與其同名的基類函數(shù),規(guī)則如下:
( 1 )如果派生類的函數(shù)與基類的函數(shù)同名,但是參數(shù)不同。此時,不論有無 virtual 關(guān)鍵字,基類的函數(shù)將被隱藏(注意別與重載混淆)。
( 2 )如果派生類的函數(shù)與基類的函數(shù)同名,并且參數(shù)也相同,但是基類函數(shù)沒有 virtual 關(guān)鍵字。此時,基類的函數(shù)被隱藏(注意別與覆蓋混淆)

31、什么是動態(tài)特性?
在絕大多數(shù)情況下, 程序的功能是在編譯的時候就確定下來的, 我們稱之為靜態(tài)特性。 反之, 如果程序的功能是在運行時刻才能確定下來的, 則稱之為動態(tài)特性。C++中, 虛函數(shù),抽象基類, 動態(tài)綁定和多態(tài)構(gòu)成了出色的動態(tài)特性。

32、在C++ 程序中調(diào)用被 C 編譯器編譯后的函數(shù),為什么要加 extern “C”聲明?
函數(shù)和變量被C++編譯后在符號庫中的名字與C語言的不同,被extern “C”修飾的變量和函數(shù)是按照C語言方式編譯和連接的。由于編譯后的名字不同,C++程序不能直接調(diào)用C 函數(shù)。C++提供了一個C 連接交換指定符號extern“C”來解決這個問題。

33、內(nèi)聯(lián)函數(shù)INline和宏定義一起使用的區(qū)別。
內(nèi)聯(lián)函數(shù)是在編譯的時候已經(jīng)做好將對應(yīng)的函數(shù)代碼替換嵌入到對應(yīng)的位置,適用于代碼較少的函數(shù)。 宏定義是簡單的替換變量,如果定義的是有參數(shù)的函數(shù)形式,參數(shù)不做類型校驗。

34、一個空類默認(rèn)存在的成員函數(shù)有哪些?
默認(rèn)構(gòu)造函數(shù)、默認(rèn)拷貝構(gòu)造函數(shù)、默認(rèn)析構(gòu)函數(shù)、默認(rèn)賦值運算符 這四個是我們通常大都知道的。但是除了這四個,還有兩個,那就是取址運算符和 取址運算符 const
即總共有六個函數(shù)。

 class Empty
 {
 public:
   Empty(); // 缺省構(gòu)造函數(shù)
   Empty( const Empty& ); // 拷貝構(gòu)造函數(shù)
   ~Empty(); // 析構(gòu)函數(shù)
   Empty& operator=( const Empty& ); // 賦值運算符
   Empty* operator&(); // 取址運算符
   const Empty* operator&() const; // 取址運算符 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ù)不能是因為虛函數(shù)采用的是虛調(diào)用的方法,
(3)內(nèi)聯(lián)成員函數(shù)的實質(zhì)是在調(diào)用的地方直接將代碼擴(kuò)展開
(4)繼承時,靜態(tài)成員函數(shù)不能被繼承的,它只屬于一個類,因為也不存在動態(tài)聯(lián)編
(5)友元函數(shù)不是類的成員函數(shù),因此也不能被繼承

36、類的靜態(tài)成員和非靜態(tài)成員有何區(qū)別?
類的靜態(tài)成員每個類只有一個,靜態(tài)成員為所有類的實例對象共享,靜態(tài)成員有靜態(tài)成員變量和靜態(tài)成員函數(shù),靜態(tài)成員變量使用前必須初始化,靜態(tài)成員變量可以被靜態(tài)成員函數(shù)和非靜態(tài)成員函數(shù)訪問,而靜態(tài)成員函數(shù)只能訪問靜態(tài)成員變量,因為靜態(tài)成員函數(shù)屬于類,其沒有this指針。非靜態(tài)成員每個對象都有一個。

37、繼承的優(yōu)缺點。
類繼承是在編譯時刻靜態(tài)定義的,且可直接使用,類繼承可以較方便地改變父類的實現(xiàn)。但是類繼承也有一些不足之處。首先,因為繼承在編譯時刻就定義了,所以無法在運行時刻改變從父類繼承的實現(xiàn)。更糟的是,父類通常至少定義了子類的部分行為,父類的任何改變都可能影響子類的行為。如果繼承下來的實現(xiàn)不適合解決新的問題,則父類必須重寫或被其他更適合的類替換。這種依賴關(guān)系限制了靈活性并最終限制了復(fù)用性。

38、在什么時候需要使用“常引用”?
如果既要利用引用提高程序的效率,又要保護(hù)傳遞給函數(shù)的數(shù)據(jù)不在函數(shù)中被改變,就 應(yīng)使用常引用。常引用聲明方式:const 類型標(biāo)識符 &引用名=目標(biāo)變量名;

39、什么是淺拷貝?什么是深拷貝?
淺拷貝是指源對象與拷貝對象共用一份實體,僅僅是引用的變量不同(名稱不同)。對其中任何一個對象的改動都會影響另外一個對象。
深拷貝是指源對象與拷貝對象互相獨立,其中任何一個對象的改動都不會對另外一個對象造成影響。
一般來說,淺拷貝就是復(fù)制那個對象的指針。深拷貝就是復(fù)制了那個對象。

40、簡述多態(tài)實現(xiàn)的原理
編譯器發(fā)現(xiàn)一個類中有虛函數(shù),便會立即為此類生成虛函數(shù)表 vtable。虛函數(shù)表的各表項為指向?qū)?yīng)虛函數(shù)的指針。編譯器還會在此類中隱含插入一個指針vptr(對vc編譯器來說,它插在類的第一個位置上)指向虛函數(shù)表。調(diào)用此類的構(gòu)造函數(shù)時,在類的構(gòu)造函數(shù)中,編譯器會隱含執(zhí)行vptr與vtable的關(guān)聯(lián)代碼,將vptr指向?qū)?yīng)的vtable,將類與此類的vtable聯(lián)系了起來。另外在調(diào)用類的構(gòu)造函數(shù)時,指向基礎(chǔ)類的指針此時已經(jīng)變成指向具體的類的this指針,這樣依靠此this指針即可得到正確的vtable,。如此才能真正與函數(shù)體進(jìn)行連接,這就是動態(tài)聯(lián)編,實現(xiàn)多態(tài)的基本原理。

41、談?wù)勀銓γ嫦驅(qū)ο蟮恼J(rèn)識
解析:面向?qū)ο罂梢岳斫獬蓪Υ恳粋€問題,都是首先要確定這個問題由幾個部分組成,而每一個部分其實就是一個對象。然后再分別設(shè)計這些對象,最后得到整個程序。傳統(tǒng)的程序設(shè)計多是基于功能的思想來進(jìn)行考慮和設(shè)計的,而面向?qū)ο蟮某绦蛟O(shè)計則是基于對象的角度來考慮問題。這樣做能夠使得程序更加的簡潔清晰。

42、C++中為什么用模板類。

  1. 可用來創(chuàng)建動態(tài)增長和減小的數(shù)據(jù)結(jié)構(gòu)
  2. 它是類型無關(guān)的,因此具有很高的可復(fù)用性。
  3. 它在編譯時而不是運行時檢查數(shù)據(jù)類型,保證了類型安全
  4. 它是平臺無關(guān)的,可移植性
  5. 可用于基本數(shù)據(jù)類型

43 、函數(shù)模板與類模板有什么區(qū)別?
函數(shù)模板的實例化是由編譯程序在處理函數(shù)調(diào)用時自動完成的,而類模板的實例化
必須由程序員在程序中顯式地指定。

44、C++是不是類型安全的?
不是。兩個不同類型的指針之間可以強(qiáng)制轉(zhuǎn)換

45、流操作符重載為什么返回引用
在程序中,流操作符>>和<<經(jīng)常連續(xù)使用。因此這兩個操作符的返回值應(yīng)該是一個仍舊支持這兩個操作符的流引用。其他的數(shù)據(jù)類型都無法做到這一點。
注意:除了在賦值操作符和流操作符之外的其他的一些操作符中,如+、-、*、/等卻千萬不能返回引用。因為這四個操作符的對象都是右值,因此,它們必須構(gòu)造一個對象作為返回值。

46、多態(tài), 虛函數(shù), 純虛函數(shù)
多態(tài):不同對象接收相同的消息產(chǎn)生不同的動作。多態(tài)包括 編譯時多態(tài)和 運行時多態(tài)
運行時多態(tài)是:通過繼承和虛函數(shù)來體現(xiàn)的。 編譯時多態(tài):運算符重載上。
虛函數(shù): 在基類中用virtual的成員函數(shù)。允許在派生類中對基類的虛函數(shù)重新定義。 基類的虛函數(shù)可以有函數(shù)體,基類也可以實例化。 虛函數(shù)要有函數(shù)體,否則編譯過不去。 虛函數(shù)在子類中可以不覆蓋。 構(gòu)造函數(shù)不能是虛函數(shù)。
純虛函數(shù):基類中為其派生類保留一個名字,以便派生類根據(jù)需要進(jìn)行定義。 包含一個純虛函數(shù)的類是抽象類。 純虛函數(shù)后面有 = 0; 抽象類不可以實例化。但可以定義指針。 如果派生類如果不是先基類的純虛函數(shù),則仍然是抽象類。 抽象類可以包含虛函數(shù)。

47、抽象類和接口的區(qū)別
在C++里面抽象類就是接口
抽象類:定義了純虛函數(shù)的類是抽象類,不能實例化。
抽象類包括抽象方法(純虛方法),也可以包含普通方法。 抽象類可以派生自一個抽象類,可以覆蓋基類的抽象方法也可以不覆蓋。
雖不能定義抽象類的實例,但是可以定義抽象類的指針。

48、將引用作為函數(shù)參數(shù)有哪些特點
(1)與指針調(diào)用效果一樣。
(2)引用傳參,內(nèi)存中并沒有產(chǎn)生副本。
(3)用指針傳遞,也要給形參分配存儲單元;并且需要使用"*變量的"的形式,可讀性差;另外,調(diào)用的地方還得用地址作為實參。

49、引用作為函數(shù)返回值類型的格式,好處和規(guī)則?

int &fun(int a) {}

好處:不會生成副本。
規(guī)則:不能返回局部變量的引用;不能返回函數(shù)內(nèi)部new分配的內(nèi)存引用;如果返回成員的話,返回const

50、結(jié)構(gòu)與聯(lián)合的區(qū)別
聯(lián)合是公用存儲單元的,任何一個時刻只有一個被選中的成員。一旦賦值后,其他成員也覆蓋了。

51、重載(overload)和重寫(override)?
重載:多個同名函數(shù),參數(shù)不同(個數(shù)不同,參數(shù)類型不同);是同一層級的函數(shù);靜態(tài)綁定;編譯期綁定。
重寫:子類重新定義父類函數(shù)的方法;是動態(tài)綁定。

52、main函數(shù)之前會執(zhí)行什么代碼?
全局變量的初始化。

53、const 與 #define相比優(yōu)點?
const: 定義常量; 修飾函數(shù)參數(shù); 修飾函數(shù)返回值; 修飾類成員函數(shù)。
好處: const 修飾的有數(shù)據(jù)類型,而宏沒有,所以可以做類型檢查;而宏僅作字符替換,無安全檢查。
const常量可以調(diào)試
宏有副作用,不加括號的話有副作用。

54、為什么基類的析構(gòu)函數(shù)是虛函數(shù)?
動態(tài)綁定,不會造成潛在的內(nèi)存泄漏

55、子類不能繼承父類的函數(shù)有哪些   
子類繼承父類大部分的資源,不能繼承的有構(gòu)造函數(shù),析構(gòu)函數(shù),拷貝構(gòu)造函數(shù),operator=函數(shù),友元函數(shù)。

56、虛函數(shù) VS 純虛函數(shù)   
虛函數(shù)為了重載和多態(tài),在基類中是有定義的,即便定義為空。在子類中可以重寫。   
純虛函數(shù)在基類中沒有定義,必須在子類中實現(xiàn)。
多態(tài)的基礎(chǔ)是繼承,需要虛函數(shù)的支持。

57、開發(fā)中常用的數(shù)據(jù)結(jié)構(gòu):   
A:數(shù)組和鏈表:     
數(shù)組大小不能動態(tài)定義。鏈表和動態(tài)分配大小的。     
數(shù)組不適應(yīng)動態(tài)增/減的情況,因為大小固定,一旦定義就不能改變。     
鏈表適合動態(tài)的增加、刪除數(shù)據(jù)。     
數(shù)組的隨機(jī)訪問快。     
數(shù)組棧中分配; 鏈表在堆中。   
B:二叉樹遍歷: 先序、中序、后序。

58、棧溢出的原因:
棧大小有限制:分過多的數(shù)組;   
遞歸調(diào)用層太深;

59、頻繁出現(xiàn)的短小的函數(shù),在c/C++中分別如何實現(xiàn)   
c中用宏定義; C++ 內(nèi)聯(lián)

60、 C++函數(shù)傳參數(shù)方式
值傳遞、指針、引用

61、 .h頭文件中的ifndef/define/endif作用   
防止頭文件重復(fù)包含

62、什么是平衡二叉樹?
左右子樹都是平衡二叉樹 且左右子樹的深度差值的絕對值不大于 1 。

63、用兩個棧實現(xiàn)一個隊列的功能?要求給出算法和思路!
設(shè) 2 個棧為 A,B, 一開始均為空 .
入隊 :
將新元素 push 入棧 A;
出隊 :
(1) 判斷棧 B 是否為空;
(2) 如果不為空,則將棧 A 中所有元素依次 pop 出并 push 到棧 B ;
(3) 將棧 B 的棧頂元素 pop 出;
這樣實現(xiàn)的隊列入隊和出隊的平攤復(fù)雜度都還是 O(1)

64、關(guān)鍵字 static 的作用是什么?
在 C 語言中,關(guān)鍵字 static 有三個明顯的作用:

  1. 在函數(shù)體,一個被聲明為靜態(tài)的變量在這一函數(shù)被調(diào)用過程中維持其值不變。
  2. 在模塊內(nèi)(但在函數(shù)體外),一個被聲明為靜態(tài)的變量可以被模塊內(nèi)所用函數(shù)訪問,但不能被模塊外其它函數(shù)訪問。它是一個本地的全局變量。
  3. 在模塊內(nèi),一個被聲明為靜態(tài)的函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用。那就是,這個函數(shù)被限制在聲明它的模塊的本地范圍內(nèi)使用。

65、什么是預(yù)編譯 , 何時需要預(yù)編譯 ?
預(yù)編譯又稱為預(yù)處理 , 是做些代碼文本的替換工作。處理 # 開頭的指令 , 比如拷貝 #include 包含的文件代碼, #define 宏定義的替換 , 條件編譯等,就是為編譯做的預(yù)備工作的階段,主要處理 # 開始的預(yù)編譯指令,預(yù)編譯指令指示了在程序正式編譯前就由編譯器進(jìn)行的操作,可以放在程序中的任何位置。

66、Itearator 各指針的區(qū)別
游標(biāo)是指針,但不僅僅是指針。游標(biāo)和指針很像,功能很像指針,但是實際上,游標(biāo)是通過重載一元的 ”*” 和 ”->” 來從容器中間接地返回一個值。將這些值存儲在容器中并不是一個好主意,因為每當(dāng)一個新值添加到容器中或者有一個值從容器中刪除,這些值就會失效。在某種程度上,游標(biāo)可以看作是句柄( handle )。通常情況下游標(biāo)( iterator )的類型可以有所變化,這樣容器也會有幾種不同方式的轉(zhuǎn)變: iterator——對于除了 vector 以外的其他任何容器,你可以通過這種游標(biāo)在一次操作中在容器中朝向前的方向走一步。這意味著對于這種游標(biāo)你只能使用 “++” 操作符。而不能使用 “--” 或 “+=” 操作符。而對于 vector 這一種容器,你可以使用 “+=” 、 “—” 、 “++” 、 “-=” 中的任何一種操作符和 “<” 、 “<=” 、 “>” 、 “>=” 、 “==” 、 “!=” 等比較運算符。

67、數(shù)組和鏈表的優(yōu)缺點
數(shù)組,在內(nèi)存上給出了連續(xù)的空間。鏈表,內(nèi)存地址上可以是不連續(xù)的,每個鏈表的節(jié)點包括原來的內(nèi)存和下一個節(jié)點的信息(單向的一個,雙向鏈表的話,會有兩個)。
數(shù)組優(yōu)于鏈表的:
A. 內(nèi)存空間占用的少。
B. 數(shù)組內(nèi)的數(shù)據(jù)可隨機(jī)訪問,但鏈表不具備隨機(jī)訪問性。
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ù)前,必須先在雙方之間建立一個TCP連接,之后才能傳輸數(shù)據(jù)。TCP提供超時重發(fā),丟棄重復(fù)數(shù)據(jù),檢驗數(shù)據(jù),流量控制等功能,保證數(shù)據(jù)能從一端傳到另一端。
UDP---用戶數(shù)據(jù)報協(xié)議,是一個簡單的面向數(shù)據(jù)報的運輸層協(xié)議。
UDP不提供可靠性,它只是把應(yīng)用程序傳給IP層的數(shù)據(jù)報發(fā)送出去,但是并不能保證它們能到達(dá)目的地。由于UDP在傳輸數(shù)據(jù)報前不用在客戶和服務(wù)器之間建立一個連接,且沒有超時重發(fā)等機(jī)制,故而傳輸速度很快

2、編寫socket套接字的步驟
服務(wù)器:建立套接字、綁定、監(jiān)聽、接收連接、讀寫數(shù)據(jù)、關(guān)閉連接
客戶端:建立套接字、連接、讀寫數(shù)據(jù)、關(guān)閉連接

3、同步IO和異步IO的區(qū)別?
A. 同步
所謂同步,就是在發(fā)出一個功能調(diào)用時,在沒有得到結(jié)果之前,該調(diào)用就不返回。
按照這個定義,其實絕大多數(shù)函數(shù)都是同步調(diào)用(例如sin isdigit等)。
但是一般而言,我們在說同步、異步的時候,特指那些需要其他部件協(xié)作或者需要一定時間完成的任務(wù)。
最常見的例子就是 SendMessage。
該函數(shù)發(fā)送一個消息給某個窗口,在對方處理完消息之前,這個函數(shù)不返回。
當(dāng)對方處理完畢以后,該函數(shù)才把消息處理函數(shù)所返回的值返回給調(diào)用者。
B. 異步
異步的概念和同步相對。
當(dāng)一個異步過程調(diào)用發(fā)出后,調(diào)用者不會立刻得到結(jié)果。
實際處理這個調(diào)用的部件是在調(diào)用發(fā)出后,通過狀態(tài)、通知來通知調(diào)用者,或通過回調(diào)函數(shù)處理這個調(diào)用。

4、進(jìn)程間通信的方式有?
進(jìn)程間通信的方式有 :共享內(nèi)存, 管道(有名管道/無名管道),Socket ,消息隊列 ,信號,信號量,內(nèi)存映射等。

5、死鎖的四個必要條件?
互斥,請求保持,不可剝奪,環(huán)路。

6、進(jìn)程和線程的差別。
線程是指進(jìn)程內(nèi)的一個執(zhí)行單元,也是進(jìn)程內(nèi)的可調(diào)度實體.與進(jìn)程的區(qū)別:
(1)調(diào)度:線程作為調(diào)度和分配的基本單位,進(jìn)程作為擁有資源的基本單位
(2)并發(fā)性:不僅進(jìn)程之間可以并發(fā)執(zhí)行,同一個進(jìn)程的多個線程之間也可并發(fā)執(zhí)行
(3)擁有資源:進(jìn)程是擁有資源的一個獨立單位,線程不擁有系統(tǒng)資源,但可以訪問隸屬于進(jìn)程的資源.
(4)系統(tǒng)開銷:在創(chuàng)建或撤消進(jìn)程時,由于系統(tǒng)都要為之分配和回收資源,導(dǎo)致系統(tǒng)的開銷明顯大于創(chuàng)建或撤消線程時的開銷。

7、多線程如何同步
windows線程同步有四種方式:臨界區(qū)、內(nèi)核對象、互斥量、信號量。
Linux線程同步有最常用的是:互斥鎖、條件變量和信號量。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,626評論 1 32
  • 幾種語言的特性 匯編程序:將匯編語言源程序翻譯成目標(biāo)程序編譯程序:將高級語言源程序翻譯成目標(biāo)程序解釋程序:將高級語...
    囊螢映雪的螢閱讀 3,058評論 1 5
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,661評論 1 51
  • 重新系統(tǒng)學(xué)習(xí)下C++;但是還是少了好多知識點;socket;unix;stl;boost等; C++ 教程 | 菜...
    kakukeme閱讀 20,419評論 0 50
  • 一個軀體,兩個世界,一個浮華,一個空寂,哪個才是你自己。2013-10-16
    麥田小圈圈閱讀 233評論 0 0

友情鏈接更多精彩內(nèi)容