1. 程式人生 > >牛客網C++知識點整理(持續更新)

牛客網C++知識點整理(持續更新)

1.堆疊的使用

在Windows下,棧是向低地址擴充套件的資料結構,是一塊連續的記憶體的區域。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個編譯時就確定的常數),如果申請的空間超過棧的剩餘空間時,將提示overflow。因此,能從棧獲得的空間較小。

堆是向高地址擴充套件的資料結構,是不連續的記憶體區域。這是由於系統是用連結串列來儲存 的空閒記憶體地址的,自然是不連續的,而連結串列的遍歷方向是由低地址向高地址。堆的大小 受限於計算機系統中有效的虛擬記憶體。由此可見,堆獲得的空間比較靈活,也比較大。
堆疊描述儲存示意圖

在C/C++中,記憶體一般分為,堆區,棧區,全域性區,文字長量區,程式程式碼區!在函式中定義的區域性變數是存在在棧區(除static區域性變數,他是存在在全域性區),動態生成的變數存在在堆區,由指標進行讀寫!全域性變數,靜態全域性變數,靜態區域性變數是存放在全域性區的! 堆是程式設計師進行申請和釋放的,因此堆是向上,也就是向高地址方向的!棧是系統進行釋放的,且棧區大小一般是定的2M,因此棧是向下,也就是向底地址方向!

全域性未初始化讀寫資料段(BSS)

未初始化讀寫據是在程式中宣告,但是沒有初始化的變數,這些變數在程式執行之前不需要佔用儲存器的空間。靜態未初始化變數也在這兒。

全域性已初始化讀寫資料段(RW data)

已初始化資料是在程式中宣告,並且具有初值的變數,這些變數需要佔用儲存器的空間,在程式執行時它們需要位於可讀寫的記憶體區域內,並具有初值,以供程式執行時讀寫。靜態已初始化變數也在這兒。

只讀資料段(RO data)

只讀資料段是程式使用的一些不會被更改的資料,使用這些數方式類似查表式的操作,由於這些變數不需要更改,因此只需要放置在只讀儲存器中即可。常量字串就是放在這裡。

程式碼區

存放函式體的二進位制程式碼。例:char *c=”hello world”

2.類中各種資料成員的初始化

const static

const static資料成員可以在類內初始化 也可以在類外,不能在建構函式中初始化,也不能在建構函式的初始化列表中初始化

static

static資料成員只能在類外,即類的實現檔案中初始化,也不能在建構函式中初始化,不能在建構函式的初始化列表中初始化;

const

const資料成員只能在建構函式的初始化列表中初始化;

普通成員

普通資料成員不能在類內初始化,可以在建構函式中初始化,也可以在建構函式的初始化列表中初始化;

3.邏輯操作符

&&具有短路特性,即只要&&前的表示式為false後,&&後的表示式將不會再做判斷。
||和&&不是左右順序的,而是&&的優先順序高於||。

4.dynamic_cast用於類繼承多型間的轉換

dynamic_cast<>用於C++類繼承多型間的轉換,分為:
1.子類向基類的向上轉型(Up Cast)
2.基類向子類的向下轉型(Down Cast)
其中向上轉型不需要藉助任何特殊的方法,只需用將子類的指標或引用賦給基類的指標或引用即可,dynamic_cast向上轉型其總是肯定成功的。
而向下轉換時要特別注意:dynamic_cast操作符,將基類型別的指標或引用安全的轉換為派生類的指標或引用。dynamic_cast將一個基類物件指標(或引用)cast到繼承類指標,dynamic_cast會根據基類指標是否真正指向繼承類指標來做相應處理。這也是dynamic_cast與其他轉換不同的地方,dynamic_cast涉及執行時類別檢查,如果繫結到引用或指標的物件不是目標型別的物件,則dynamic_cast失敗。如果是指標型別失敗,則dynamic_cast的返回結果為0,如果是引用型別的失敗,則丟擲一個bad_cast錯誤。
注意:dynamic_cast在將父類cast到子類時,父類必須要有虛擬函式。因為dynamic_cast執行時需要檢查RTTI資訊。只有帶虛擬函式的類執行時才會檢查RTTI。

5.new和malloc的區別

new會分配記憶體,並呼叫類的建構函式建立物件,而malloc只是分配記憶體,不呼叫類的建構函式建立物件。new一般和delete連用,而malloc和free連用。

6.私有繼承

私有繼承中,基類的私有成員在子類中是不可訪問的。並不是私有的。

7.變數的預設初始化

棧空間上面的區域性變數預設初始化為隨機值。
全域性整形變數和靜態stati整形c變數預設初始值為0。

8.運算子函式作為成員函式

思考重點在“ 成員函式”上,運算子過載為成員函式時:
成員函式隱含一個引數的this指標,所以單目運算子過載為成員函式時,無引數;雙目運算子過載為成員函式時,有一個引數。
一般,單目運算子過載為成員函式;雙目運算子過載為友元函式。

9.前置和後置++,- -運算子

一般情況下,優先使用前置運算子,後置運算子會帶來效能問題。詳細解答見《C++ Primer第五版》:
前置和後置運算子

10.sizeof

sizeof用來計算某種型別佔用的記憶體大小。如下所示:
測試程式
從執行結果看:
執行結果
sizeof(vector<string>)的大小為12位元組,這是因為vector類中有三個指標,每個指標佔4個位元組,所以是三位元組。無論這是一個什麼型別的vector。
測試程式
sizeof()用作類的物件,計算的是類中非靜態成員的大小總和。對於空類來說,大小為1。

11.記憶體對齊

規則:
1、第一個資料成員放在offset為0的地方,以後每個資料成員的對齊按照#pragma pack指定的數值和這個資料成員自身長度中,比較小的那個進行。
2、在資料成員完成各自對齊之後,類(結構或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大資料成員長度中,比較小的那個進行。
很明顯#pragma pack(n)作為一個預編譯指令用來設定多少個位元組對齊的。值得注意的是,n的預設數值是按照編譯器自身設定,一般為8,合法的數值分別是1、2、4、8、16。
即編譯器只會按照1、2、4、8、16的方式分割記憶體。若n為其他值,是無效的。
牛客試題
A中int佔四位元組,short兩個位元組,int四位元組,short還餘兩個位元組,不夠,因此為4+2+2+4+1+3=16
B中char佔1個位元組,short餘兩個位元組,夠,因此為4+2+1+1+4=12
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述