天天看點

編譯指令的了解

預編譯

1、處理所有的注釋,以空格代替

2、将所有的#define删除,并且展開所有的宏定義

3、處理條件編譯指令#if,#ifdef,#elif,#else,#endif

4、處理#include,展開被包含的檔案

5、保留編譯器需要使用的#pragma指令

編譯

1、對預處理檔案進行一系列詞法分析,文法分析和語義分析

2、詞法分析主要分析關鍵字,标示符,立即數等是否合法

3、文法分析主要分析表達式是否遵循文法規則

4、語義分析在文法分析的基礎上進一步分析表達式是否合法

5、分析結束後進行代碼優化生成相應的彙編代碼檔案

彙編

1、彙編器将彙編代碼轉變為機器可以執行的指令

2、每個彙編語句幾乎都對應一條機器指令

連結器的作用

1、連接配接器的主要作用是把各個子產品之間互相引用的部分

2、處理好,使得各個子產品之間能夠正确的銜接。

編譯器将編譯工作主要分為預處理,編譯和彙編三部

1、連接配接器的工作是把各個獨立的子產品連結為可執行程式

2、靜态連結在編譯期完成,動态連結在運作期完成

#define

1、#define表達式給有函數調用的假象,卻不是函數

2、#define表達式可以比函數更強大

3、#define表達式比函數更容易出錯

4、最好不要定義時間點的量,如i++,

5、#definept允許這樣定義,但沒有仍和意義,将pt的内容替換為空,或者說,是直接删去

6、define可以替代任何變量,這個操作隻是預編譯中,替換而已

7、define的功能比函數強大,但是漏洞比函數大的多。

定義的内置宏,用于實作發現那個行出錯的消息。

__line__目前行

__file____date__目前的時間和檔案名

。。。

條件編譯

1、條件編譯的行為類似于c語言中的if…else

2、條件編譯是預編譯訓示指令,用于控制是否編譯某段代碼

即在預編譯時去除掉一些代碼,選擇性的進行編譯

#include的困惑

1、#include的本質是将已經存在的檔案内容嵌入到目前檔案中

2、#include的間接包含同樣會産生嵌入檔案内容的動作

如果間接的包含相同的頭檔案怎麼辦?會不會出錯?

會出錯,但是處理的方式是ifndef_headname_h_

條件編譯的意義:

1、條件編譯使得我們可以按不同的條件編譯不同的代碼段,

因而可以産生不同的目标代碼

2、#if…#else…#endif被預編譯器處理;而if…else語句被

編譯器處理,必然被編譯進目标代碼

3、實際工程中條件編譯主要用于一下兩種情況:

不同的生産線共用一份代碼

區分編譯産品的調試版和釋出版

通過編譯器指令行能夠定義預處理器使用的宏

條件編譯可以避免重複包含頭同一個頭檔案

條件編譯是在工程開發中可以差別不同産品線的代碼

條件編譯可以定義産品的釋出版和調試版

#error用于生成一個編譯錯誤消息,并停止編譯

用法

#errormessage

注:message不需要用雙引号包圍

#error編譯訓示字用于自定義程式員特有的編譯錯誤消息

類似的,

#warning用于生成編譯警告,但不會停止編譯

#line用于強制指定新的行号和編譯檔案名,并對源程式

的代碼重新編号

#linenumberfilename

注:filename可省略

#line編譯訓示字的本質是重定義__line__和__file__

用途:無關表示部分的代碼有某個人開發的,開發的那個程式段出現錯誤,

也就是告訴調試者的寫的代碼的相對位置進行檢錯。

現在有個更好的處理技術,來處理這個問題的。

#pragma簡介

1、#pragma是編譯器訓示字,用于訓示編譯器完成一些特定的動作

2、#pragma所定義的很多訓示字是編譯器和作業系統特有的

3、#pragma在不同的編譯器間是不可移植的

4、預處理器将忽略它不認識的#pragma指令

5、兩個不同的編譯器可能以兩種不同的方式解釋同一條#pragma指令

6、确定程式設計的的版本,便于差錯,用于顯示自己的程式的版本

提示作者版本是否正确

#pragmamessage("compileandroidsdk2.0...")

深入:

1、預處理器将忽略它不認識的#pragma指令

2、兩個不同的編譯器可能以兩種不同的方式解釋同一條#pragma指令

一般用法:

#pragmaparameter

注:不同的parameter參數文法和意義各不相同

#pragma的記憶體對齊

構體變量是否可以直接用memcmp函數

進行相等判斷?為什麼?

不可以,因為記憶體對齊會影響到兩個大小形同,可能沒用的資料也進行了比較

繼續閱讀