舊房改造室內(nèi)裝修設(shè)計公司seo黑帽有哪些技術(shù)
目錄
gcc/g++--編譯器
介紹
使用格式
通用選項
編譯選項
鏈接選項
程序編譯過程
預(yù)處理(宏替換)
編譯 (生成匯編)
分析樹(parse tree)
編譯優(yōu)化
刪除死代碼
寄存器分配和調(diào)度
強度削弱
內(nèi)聯(lián)函數(shù)
生成目標(biāo)代碼?
匯編 (生成二進(jìn)制代碼)
鏈接(生成可執(zhí)行文件)?
函數(shù)庫
引入
介紹
動態(tài)鏈接
?示例?編輯
gcc/g++--編譯器
介紹
是GNU編譯器集合(GNU Compiler Collection)中的兩個重要組件,用于編譯和鏈接程序
使用格式
g++也一樣
一般是:
通用選項
編譯選項
eg:
鏈接選項
eg:
?
程序編譯過程
預(yù)處理(宏替換)
預(yù)處理后,生成.i文件,可以通過-E選項拿到編譯的中間過程中的.i文件
編譯 (生成匯編)
- 從.i文件中,編譯器會對其進(jìn)行詞法/語法/語義分析,并且會對代碼進(jìn)行優(yōu)化
- 編譯后生成.s文件,使用-S選項可以拿到這個.s文件
分析樹(parse tree)
- 是一種用于表示源代碼語法結(jié)構(gòu)的樹狀數(shù)據(jù)結(jié)構(gòu),通常通過語法分析器生成
- 它反映了源代碼中的各個語法元素(如關(guān)鍵字、運算符、變量、函數(shù)調(diào)用等)之間的嵌套關(guān)系,幫助編譯器理解代碼的結(jié)構(gòu)并執(zhí)行后續(xù)的編譯步驟
- 它將源代碼分解為一個個語法單元,然后根據(jù)編程語言的語法規(guī)則將這些單元組合成樹狀結(jié)構(gòu)
編譯優(yōu)化
為了提高計算機程序的執(zhí)行效率和性能,會進(jìn)行編譯優(yōu)化
刪除死代碼
實際不會產(chǎn)生作用的代碼:
- 執(zhí)行不到的代碼
- 執(zhí)行的到但是沒有用的代碼(沒有使用過的變量))
寄存器分配和調(diào)度
- 很多編譯器會將 for循環(huán)的循環(huán)控制變量 調(diào)度到寄存器訪問(寄存器快!)
強度削弱
- 用執(zhí)行時間較短的操作(指令)去代替一個耗時操作
- 下面的代碼,由于需要使用的是計算的結(jié)果,因此中間數(shù)可以被替換掉(比如*變+):
#include <iostream> using namespace std; int main() { int a1 = 5; int b1 = 17; int c1 = a1 * b1; cout << c1 << endl; // 強度削弱 int a2 = 5; int b2 = a2 << 4; int c2 = a2 + b2; cout << c2 << endl; return 0; }
內(nèi)聯(lián)函數(shù)
除了編譯器自動做出的優(yōu)化,程序員在編寫的時候也需要手動進(jìn)行優(yōu)化(因為編譯器沒有我們想的那么智能啦)
內(nèi)聯(lián)函數(shù)(將 短小但常用的函數(shù) 定義為內(nèi)聯(lián)函數(shù)(inline),可以減少函數(shù)調(diào)用開銷)
但其實內(nèi)聯(lián)函數(shù)也可以被編譯器自動識別并使用
生成目標(biāo)代碼?
- 將經(jīng)過語法分析和語義分析的源代碼轉(zhuǎn)化為目標(biāo)代碼,這個目標(biāo)代碼可以是匯編語言、中間代碼或直接的機器代碼,具體取決于編譯器的設(shè)計和目標(biāo)平臺
- 代碼生成器的主要任務(wù)是將 [高級編程語言的源代碼] 翻譯成 [目標(biāo)平臺的可執(zhí)行代碼]
?
匯編 (生成二進(jìn)制代碼)
中間過程也有很多,就不介紹了
?
鏈接(生成可執(zhí)行文件)?
函數(shù)庫
引入
- 我們在使用庫函數(shù)時,是直接調(diào)用+引用頭文件
- 但是頭文件中只有函數(shù)聲明,那么實現(xiàn)在哪里呢?
介紹
- 函數(shù)庫分為靜態(tài)庫和動態(tài)庫?
- 使用靜態(tài)庫的方式就是靜態(tài)鏈接,使用動態(tài)庫的方式就是動態(tài)鏈接
- 其中,靜態(tài)庫內(nèi)存開銷大,但不需要庫文件,后綴.a
- 動態(tài)庫開銷很小,一份庫文件可以被多個程序共享使用,所以一般都會使用動態(tài)鏈接,后綴.so
動態(tài)鏈接
- 當(dāng)程序運行時,動態(tài)鏈接器會查找并加載所需的庫,根據(jù)可執(zhí)行文件中的引用信息,將庫文件映射到進(jìn)程的地址空間
- 動態(tài)鏈接器解析程序中的未解析引用,將其與庫中的實際函數(shù)或符號關(guān)聯(lián)起來
- 程序在運行過程中,會調(diào)用庫中的函數(shù)或方法
- 并且,庫是在運行時加載的,因此庫的更新可以在不停止程序的情況下進(jìn)行
?示例
- 直接編譯生成的是那個test(也就是使用了gcc的動態(tài)鏈接)
- test_static是在編譯的時候,選擇了使用靜態(tài)庫鏈接生成的
- 可以看到大小差很多
?
總結(jié)來說,編譯過程的選項是" esc ",只不過在實際使用時,只有c是小寫字母,其他都是大寫字母