編譯指令的理解

預編譯

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的內容替換爲空,或者說,是直接刪去

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

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

定義的內置宏,用於實現發現那個行出錯的消息。

__LINE__當前行

__FILE____DATE__當前的時間和文件名

。。。

條件編譯

1、條件編譯的行爲類似於C語言中的ifelse

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

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

#include的困惑

1#include的本質是將已經存在的文件內容嵌入到當前文件中

2#include的間接包含同樣會產生嵌入文件內容的動作

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

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

條件編譯的意義:

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

因而可以產生不同的目標代碼

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

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

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函數

進行相等判斷?爲什麼?

不可以,因爲內存對齊會影響到兩個大小形同,可能沒用的數據也進行了比較

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