牛客網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
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

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