首頁技術(shù)文章正文

100家IT名企面試題系列之c/c++面試寶典

更新時間:2018-08-16 來源:黑馬程序員技術(shù)社區(qū) 瀏覽量:

1.new、delete、malloc、free關(guān)系

delete會調(diào)用對象的析構(gòu)函數(shù),和new對應free只會釋放內(nèi)存,new調(diào)用構(gòu)造函數(shù)。malloc與free是C++/C語言的標準庫函數(shù),new/delete是C++的運算符。它們都可用于申請動態(tài)內(nèi)存和釋放內(nèi)存。對于非內(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ù)的任務強加于malloc/free。因此C++語言需要一個能完成動態(tài)內(nèi)存分配和初始化工作的運算符new,以及一個能完成清理與釋放內(nèi)存工作的運算符delete。注意new/delete不是庫函數(shù)。

2.delete與 delete []區(qū)別

delete只會調(diào)用一次析構(gòu)函數(shù),而delete[]會調(diào)用每一個成員的析構(gòu)函數(shù)。在More Effective  C++中有更為詳細的解釋:“當delete操作符用于數(shù)組時,它為每個數(shù)組元素調(diào)用析構(gòu)函數(shù),然后調(diào)用operatordelete來釋放內(nèi)存?!眃elete與New配套,delete []與new []配套

  MemTest*mTest1=newMemTest[10];

  MemTest*mTest2=newMemTest;

  int*pInt1=newint[10];

  int*pInt2=newint;

  delete[]pInt1;  //-1-

  delete[]pInt2;  //-2-

  delete[]mTest1;//-3-

  delete[]mTest2;//-4-

  在-4-處報錯。

這就說明:對于內(nèi)建簡單數(shù)據(jù)類型,delete和delete[]功能是相同的。對于自定義的復雜數(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就會認為指向的是單個對象,否則,它就會認為指向的是一個數(shù)組。

3.C C++ JAVA共同點,不同之處?4.繼承優(yōu)缺點。

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

(待補充)


5.C++有哪些性質(zhì)(面向?qū)ο筇攸c)

封裝,繼承和多態(tài)。

在面向?qū)ο蟪绦蛟O計語言中,封裝是利用可重用成分構(gòu)造軟件系統(tǒng)的特性,它不僅支持系統(tǒng)的可重用性,而且還有利于提高系統(tǒng)的可擴充性;消息傳遞可以實現(xiàn)發(fā)送一個通用的消息而調(diào)用不同的方法;封裝是實現(xiàn)信息隱蔽的一種技術(shù),其目的是使類的定義和實現(xiàn)分離。

6.子類析構(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ù)JAVA無析構(gòu)函數(shù)深拷貝和淺拷貝

7.多態(tài),虛函數(shù),純虛函數(shù)
8.求下面函數(shù)的返回值(微軟)

int func(x) 

    int countx = 0; 
    while(x) 
    { 
          countx ++; 
          x = x&(x-1); 
     } 
    return countx; 
}  

假定x = 9999。 答案:8

思路:將x轉(zhuǎn)化為2進制,看含有的1的個數(shù)。

9.什么是“引用”?申明和使用“引用”要注意哪些問題?

答:引用就是某個目標變量的“別名”(alias),對應用的操作與對變量直接操作效果完全相同。申明一個引用的時候,切記要對其進行初始化。引用聲明完畢后,相當于目標變量名有兩個名稱,即該目標原名稱和引用名,不能再把該引用名作為其他變量名的別名。聲明一個引用,不是新定義了一個變量,它只表示該引用名是目標變量名的一個別名,它本身不是一種數(shù)據(jù)類型,因此引用本身不占存儲單元,系統(tǒng)也不給引用分配存儲單元。不能建立數(shù)組的引用。

10.將“引用”作為函數(shù)參數(shù)有哪些特點?

(1)傳遞引用給函數(shù)與傳遞指針的效果是一樣的。這時,被調(diào)函數(shù)的形參就成為原來主調(diào)函數(shù)中的實參變量或?qū)ο蟮囊粋€別名來使用,所以在被調(diào)函數(shù)中對形參變量的操作就是對其相應的目標對象(在主調(diào)函數(shù)中)的操作。

(2)使用引用傳遞函數(shù)的參數(shù),在內(nèi)存中并沒有產(chǎn)生實參的副本,它是直接對實參操作;而使用一般變量傳遞函數(shù)的參數(shù),當發(fā)生函數(shù)調(diào)用時,需要給形參分配存儲單元,形參變量是實參變量的副本;如果傳遞的是對象,還將調(diào)用拷貝構(gòu)造函數(shù)。因此,當參數(shù)傳遞的數(shù)據(jù)較大時,用引用比用一般變量傳遞參數(shù)的效率和所占空間都好。

(3)使用指針作為函數(shù)的參數(shù)雖然也能達到與使用引用的效果,但是,在被調(diào)函數(shù)中同樣要給形參分配存儲單元,且需要重復使用"*指針變量名"的形式進行運算,這很容易產(chǎn)生錯誤且程序的閱讀性較差;另一方面,在主調(diào)函數(shù)的調(diào)用點處,必須用變量的地址作為實參。而引用更容易使用,更清晰。

11.在什么時候需要使用“常引用”? 

如果既要利用引用提高程序的效率,又要保護傳遞給函數(shù)的數(shù)據(jù)不在函數(shù)中被改變,就應使用常引用。常引用聲明方式:const 類型標識符 &引用名=目標變量名;

例1

int a ;
const int &ra=a;
ra=1; //錯誤
a=1; //正確

例2

string foo( );
void bar(string & s);

那么下面的表達式將是非法的:

bar(foo( ));
bar("hello world");

原因在于foo( )和"hello world"串都會產(chǎn)生一個臨時對象,而在C++中,這些臨時對象都是const類型的。因此上面的表達式就是試圖將一個const類型的對象轉(zhuǎn)換為非const類型,這是非法的。引用型參數(shù)應該在能被定義為const的情況下,盡量定義為const 。

   

本文版權(quán)歸黑馬程序員人工智能+Python培訓學院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處。謝謝!

作者:黑馬程序員人工智能+Python培訓學院

首發(fā):http://python.itheima.com/

分享到:
在線咨詢 我要報名
和我們在線交談!