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