C/C++基础知识点(二)
文章目錄
- 13.C++如何定義常量,常量放在內存的哪個位置?
- 14.const修飾成員函數的目的是什么?
- 15.以下幾行代碼的區別?
- 16.隱式類型轉換
- 17.new/delete與malloc/free的區別
- 18. RTTI
- 19.C++如何處理返回值
- 20.C++中拷貝賦值函數的形參能否進行值傳遞?
- 21.STL有什么基本組成
- 22.STL中set和map如何實現的?
- 23.STL迭代器如何刪除元素
- 24.vector和list的區別
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
總結
以上是生活随笔為你收集整理的C/C++基础知识点(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C/C++基础知识点(一)
- 下一篇: C/C++基础知识点(三)