C/C++基礎知識點(二)

13.C++如何定義常量,常量放在內存的哪個位置?

常量在C++裏的定義是一個top-level const加上對象類型,常量定義必須初始化。對於局部對象,常量存放在棧區,對於全局對象,常量存放在全局/靜態存儲區。對於字面值常量,常量存放在常量存儲區。

14.const修飾成員函數的目的是什麼?

const修飾成員函數標明函數調用不會對對象作出任何更改,事實上,如果確認不會對對象做更改,就應該爲函數加上const限定,這樣無論const對象還是普通對象都可以調用該函數。

15.以下幾行代碼的區別?

const char * arr = "123"; //字符串123保存在常量區,const本身修飾arr指向的值不能通過arr去修改,但是字符串"123"在常量區,本來就不能修改,所以加不加const都一樣的。
char * brr = "123"; //字符串"123"保存在常量區,這個arr指針指向的是同一個位置,同樣不能用brr去修改"123"的值。
const char crr[] = "123"; //這裏123本來是在棧上的,但是編譯器可能會做某些優化,將其放到常量區。
char drr[] = "123";//字符串123保存在棧區,可以通過drr去修改。

16.隱式類型轉換

首先,對於內置類型,低精度的變量給高精度變量賦值會發生隱式類型轉換,其次,對於只存在單個參數的構造函數的對象構造來說,函數調用可以直接使用該參數傳入,編譯器會自動調用其構造函數生成臨時對象。

17.new/delete與malloc/free的區別

首先,new/delete是C++的關鍵字,而malloc/free是C語言的庫函數,後者使用必須指明申請內存空間的大小,對於類類型的對象,後者不會調用構造函數和析構函數。

18. RTTI

RTTI 全稱:運行時類型檢查。在C++層面主要體現在dynamic_cast和typeid,VS中虛函數表的-1位置存放了指向type_info的指針,對於存在虛函數的類型,typeid和dynamic_cast都會去查詢type_info.

關於RTTI詳細介紹請查看這裏

19.C++如何處理返回值

生成一個臨時變量,把它的引用作爲函數參數傳入函數內。

20.C++中拷貝賦值函數的形參能否進行值傳遞?

不能。如果是這種情況下,調用拷貝構造函數的時候,首先要將實參傳遞給形參,這個傳遞的時候又要調用拷貝構造函數,如此循環,無法完成拷貝,棧也會滿。

21.STL有什麼基本組成

STL主要由以下幾個部分組成:容器、迭代器、仿函數、算法、分配器、配接器。
它們之間的關係:分配器給容器分配存儲空間,算法通過迭代器獲取容器中的內容,仿函數可以協助算法完成各種操作,配接器用來套接適配仿函數。

22.STL中set和map如何實現的?

  • set:集合。所有元素都會根據元素的值自動被排序,且不允許重複。底層實現:紅黑樹。
    set底層是通過紅黑樹(RB-tree)來實現的,由於紅黑樹是一種平衡二叉搜索樹,自動排序的效果很不錯,set以此爲底層機制。並且set的所有操作接口,都是轉調用RB-tree的操作。
    適用場景:有序不重複集合。
  • map:映射。map的所有元素都是pair,同時擁有鍵值key和實值value,pair的第一元素被視爲鍵值,第二元素被視爲實值,所有元素都會根據元素的鍵值自動被排序。不允許鍵值重複。底層實現用紅黑樹。
    適用場景:有序鍵值對不重複映射。

23.STL迭代器如何刪除元素

1.對於序列容器vector,deque來說,適用erase(itertor)後,後邊的每個元素的迭代器都會失效,後邊的每個元素都會往前移動一個位置,但是erase會返回下一個有效的迭代器。

2.對於關聯容器map,set來說,適用了erase(itertor)後,當前元素的迭代器失效,但是其結構是紅黑樹,刪除當前元素的,不會影響到下一個元素的迭代器,所以在調用erase之前,記錄下一個元素的迭代器即可。

3.對於list來說,它使用了不連續分配的內存,並且它的erase方法也會返回下一個有效的itertor,因此上面兩種正確的方法都可以使用。

24.vector和list的區別

1.概念

  • vector:連續存儲的容器,動態數組,在堆上分配空間,底層實現:數組。當vector增加新元素時,如果未超過當時的容量,則還有剩餘空間,那麼直接添加到最後,然後調整迭代器。如果沒有空間了,就會重新配置原有元素個數的兩倍空間,然後將原空間元素通過複製的方式初始化新空間,再向新空間添加元素,然後析構並釋放原有空間,之前的迭代器會失效。
    性能:
    插入:在最後插入(空間夠):很快
    在最後插入(空間不夠):需要內存申請和釋放,以及對之前數據進行拷貝
    在中間插入(空間夠):內存拷貝
    在中間插入(空間不夠):需要內存申請和釋放,以及對之前的數據機型拷貝
    刪除:在最後刪除很快
    在中間刪除:內存拷貝
    適用場景:經常隨機訪問,且不經常對非尾字節點進行插入刪除。
  • list:動態鏈表,在堆上分配空間,每插入一個元素都會分配空間,每刪除一個元素都會釋放空間。底層實現:雙向鏈表。
    性能:
    訪問:隨機訪問性能很差,只能快速訪問頭尾節點
    插入:很快,一般是常數開銷
    刪除:很快,一般是常數開銷
    適用場景:經常插入刪除大量數據

2.區別

  • vector底層實現是數組,list底層實現是雙向鏈表
  • vector支持隨機訪問,list不支持
  • vector是順序內存,list不是
  • vector在中間節點進行插入刪除會導致內存拷貝,list不會
  • vector隨機訪問性能好,插入刪除性能差,list相反
  • vector一次性分配好內存,不夠時才進行2倍擴容,list每次插入新節點都會進行內存申請

3.應用
vector擁有一段連續的內存空間,因此支持隨機訪問,如果需要高效的隨機訪問,而不在乎刪除和插入的效率,使用vector
list擁有一段不連續的內存空間,如果需要高效的插入和刪除,而不關心隨機訪問,使用list

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章