程式設計師的自我修養 讀書筆記

2022-02-27 01:44:13 字數 2709 閱讀 6507

1:注意不要反回指向棧記憶體的指標或引用,因為在函式返回時改記憶體已經被銷毀了

2:c/c++沒有辦法知道指標所指的記憶體容量大小 當陣列作為引數傳遞時,陣列將退化成相同型別的指標 不要指望要指標引數去申請動態記憶體,因為函式會為產生乙個臨時變數指向引數的記憶體,當函式內分配記憶體時,將記憶體的位址賦給了臨時引數,而沒有給實參賦值,所有實參沒有發生任何變化,應該修改的是指標所指的內容,而不是修改指標的指向,所有可以用指向指標的指標

3:過載和內聯機制既可用於全域性函式也可用於類的成員函式,const和virtual機制即用於類的成員函式

4:在繼承關係中,非虛方法:呼叫指標型別的方法;虛方法:呼叫指標所指的物件型別的方法 非虛方法和預設引數都是靜態繫結,在繼承關係中只跟指標型別有關,跟指標所指的物件的實際型別無關

5:互相引用的兩個類,兩個類最好宣告在同乙個標頭檔案中,定義可以放在同乙個或兩個的檔案中;這樣即解決了互相引用的問題,同時解決了在乙個類中不能正確delete另乙個類

6:處理#include預編譯指令,將被包含的檔案插入到預編譯指令的位置,這個過程是遞迴進行的

7:c語言的編譯後執行語句都編譯成機器**,儲存在.text段

.data:已初始化的全域性變數和區域性靜態變數

.bss:為未初始化的全域性變數和區域性靜態變數預留位置而已(不佔磁碟空間,執行時當然是佔空間的)

.rodata:存放唯讀資料,const修飾的變數,常量字串;(傳說中的字串池,暈,別說得這麼高階,只不過是在編譯的時候就分配好了記憶體)

8:程式源**被編譯後主要分成兩種段:程式指令和程式資料 分開的好處:

1:資料和指令分別被對映到兩個虛存區域,資料可讀寫,指令唯讀;

2:cpu的高階快取分為資料快取和指令快取

9:可執行檔案中的**段和資料段都是由輸入的目標檔案中相應的段合併而來的

10:作用域:全域性變數不管定義在**(.h或.cpp)整個解決方案都可見,定義在標頭檔案中的靜態全域性變數整個解決方案都可以見,定義在實現檔案(.cpp)中的靜態變數只有這個檔案可見,類中的public靜態變數作用域是整個解決方案,可以通過類名使用這個靜態變數,而private靜態變數作用域則是這個類,方法中的靜態變數作用域就是這個方法

14:在編譯的時候每個目標檔案都會有乙個符號表,如果a檔案引用了b檔案中的變數或方法,那麼在符號表中就會標記這些變數或方法是沒有定義了,在鏈結的時候如果沒有找到這些變數或方法的定義,在鏈結的時候就會報符號未定義錯誤

15:靜態裝入:程式執行是所需要的指令和資料必須在記憶體中才能正常執行,最簡單的辦法就是將程式執行所需要的指令和資料全部裝入記憶體中

動態裝入的基本原理:程式執行有區域性性,將程式最常用的部分駐留在記憶體中,不太常用的資料存放在磁碟中

16:建立乙個獨立的虛擬位址空間:將虛擬空間和物理空間對映 讀取可執行檔案頭,並建立虛擬空間與可執行檔案的對映關係:虛擬空間和執行檔案對映 將cpu的指令暫存器設定成可執行檔案的入口位址,啟動執行

1:所有的介面函式都應該是抽象的,所有的方法都應該是純虛的

2:所有的全域性函式都應該使用extern c來防止名字修飾的不相容,並且匯出函式都應是_stdcall呼叫規範的,    這樣即使使用者本身的程式是預設以_cdecl方式編譯的,對於   dll的呼叫也能夠正確

3:不要使用c++標準庫stl

4:不要使用異常

5:不要使用虛析構函式,可以建立乙個destory方法並且充值delete操作符並呼叫destory()方法

6:不要再dll裡面申請記憶體,而且在dll外釋放(或者相反),不同的dll和可執行檔案可能使用不同的堆,在乙個堆裡面申請的記憶體而在另乙個堆裡面釋放會導致錯誤,對於記憶體分配相關的函式不應該是inline的,以防止它在編譯時被展開到不同的dll和可執行檔案中

7:不要再介面中使用過載方法,因為不同的編譯器對於vtable的安排可能不同

18:棧一般儲存的內容:

2:臨時變數:包括函式的非靜態區域性變數以及編譯器自動生成的其他臨時變數

3:儲存上下文:包括函式呼叫前後需要保持不變的暫存器

19:多型的實現原理:

1:含有虛方法的類都有乙個虛函式表

2:子類的虛方法會覆蓋父類對應的虛方法

3:含有虛方法的類的每個例項都有乙個指向虛方法表的指標,如果虛繼承的話可能會有多個

4:根據3中的指標呼叫虛方法表中對應的虛方法

20:全域性構造與析構:

編譯器將兩個段.init和.finit這兩個段拼成兩個函式_init()和_finit(),這兩個函式先後於main函式執行,當然main函式並不是程式的入口,_start才是入口函式,.init段裡面有個陣列,陣列中存放所有全域性建構函式的指標,在執行函式_init()時會執行全域性變數的建構函式,也就是說在呼叫main函式前,全域性變數已經初始化好了,main函式執行完成之後,在執行_finit(),即全域性變數的析構。

對每個編譯單元(.cpp),編譯器會遍歷其中所有的全域性變數,生成乙個特殊的函式_global_i_hw,這個函式的作用就是初始化當前編譯單元中的所有全域性變數,如果這個特殊函式存在(即有全域性變數),那麼編譯器會在目標檔案的.ctors段中存放這個函式的乙個指標,聯結器在鏈結所有的目標檔案的時候,會將同名的段合併在一起,每個目標檔案的.ctors段也就合併在一起了,這樣.ctors段中存放的就是每個目標檔案中全域性建構函式的指標,執行這些全域性建構函式,全域性變數就初始化好了。

全域性析構的過程我想聰明的你不看也應該知道個大概,

21:未完.....待續......

程式設計師的自我修養 讀書筆記

第一部分 溫故而知新 第一章 介紹基本的背景知識 作業系統 執行緒 硬體 1 關於c語言中的hello world這些問題你都清楚嗎?2 計算機硬體裝置的三個核心部件 1 處理器cpu 2 記憶體 3 i o控制晶元 4 作業系統的功能 1 提供抽象介面。2 管理硬體資源 5 多道程式 分時系統 多...

《程式設計師的自我修養》讀書筆記

1 最佳實踐 作為一名程式設計師,你也需要嘗試去理解那些軟體領域最本質的東西,而我的建議就是學習那些最佳實踐。最佳實踐 bestpractice 是乙個管理學概念,即 可使結果最優,並減少出錯可能性的某種技術或方法。最佳實踐一定是要經受住實踐檢驗才得出的。學習本質 是 以慢打快 的策略,但這種策略短...

程式設計師的自我修養 讀書筆記

哦,笑吧,科廷,老夥計。這是上帝,或者也可以說是命運或自然,跟我們開的乙個玩笑。不過,不管這傢伙是誰或是什麼,他真幽默,哈哈!霍華德,碧血沙金 專業主義不但象徵著榮譽與驕傲,而且明確意味著責任與義務。假如不小心在程式中寫了乙個bug,以致於公司損失10萬,對於非專業人士來說,只會聳聳肩 狀況總是難免...