理解程式編譯預處理與鏈結過程

2021-07-24 07:53:08 字數 3101 閱讀 5517

首先熟悉一些預處理識別符號

__file__  :進行編譯的檔案

__line__  :檔案當前行號

# :使用預處理器將巨集引數轉換成乙個字串

##:將位於它兩邊的符號連線成乙個符號。

示例 :

__file__  :用linux指令來觀察它的預處理結果和最後輸出的結果

#include

int main()

__line__ ,__date__  ,__time__也是同理,因此將它們一次寫完觀察預處理之後的結果即gcc -e  mytest.c -o mytest.i,也可以直接觀察程式執行完之後的結果即gcc mytest.c 然後用./a.out觀察程式執行完的結果

由以上結果可以看出程式在預處理之後就已經將__line__ ,__date__  ,__time__這些預處理識別符號用 」mytest.c",4,"nov  3 2016 ","10:24:40"替換了即預處理之後的結果就等同於程式執行完之後的結果。

示例:'#『使用預處理器將巨集引數轉換成乙個字串**如下:

#define m 10

#define print(format,value) printf("the value of" #value"is" format"\n",value);

#include

int main()

預處理之後的結果:

由以上的結果就可以看出在預處理之後巨集引數通過』#『就已經轉換成乙個字串,而程式執行完之後的結果也是巨集引數m變成了乙個字串。

』##『使用是將位於它兩邊的符號連線成乙個符號

2、了解巨集和函式

1、巨集可以非常頻繁地用於執行簡單的運算,可以進行引數的替換

2、巨集可以進行臨近字串的拼接並且可以替換掉其中的一部分

3、對函式中的實參和形參都要定義型別,二者的型別要求一致,如不一致,應進行型別轉換;而巨集不存在型別問題,巨集名無型別,它的引數也無型別,只是乙個符號代表,展開時帶入指定的字元即可。巨集定義時,字串可以是任何型別的資料。

4、巨集不可以出現遞迴

5、引數巨集在定義時要多加小心,多加括號。

6、:函式呼叫時,先求出實參表示式的值,然後帶入形參。而使用帶參的巨集只是進行簡單的字元替換。

在考慮效率的時候,可以考慮使用巨集

7、在巨集定義**塊時加上do while(0)

和函式相比,使用巨集的不利之處在於每次使用巨集時,乙份巨集定義**拷貝將插入到程式中,除非巨集非常短,否則使用巨集可能會大幅度增大**長度。但和函式相比有一些任務使用函式無法實現比如:

#define malloc(n,type) ((type*)malloc((n)*sizeof(type)))

int *pi=malloc(25,int);

這個巨集的第二個引數是一種型別,它無法作為函式引數進行傳遞

這個巨集替換完成之後:

int *pi=((int*)malloc((25)*sizeof(int)));

4 帶副作⽤的巨集引數

當巨集引數在巨集定義中出現次數超過⼀次時,如果這個引數具有副作

⽤,那麼當你使⽤這個巨集時就可能出現危險,導致不可預料的結果。副作

⽤就是在表示式求值時出現的永久性效果。例如,下⾯表示式

x + 1;

可以執⾏⼏百次,他每次獲得結果都是⼀樣的,這個表示式不具有副作

⽤。但是

x ++;    

就有副作⽤:它增加x的值。當這個表示式下⼀次執⾏時,他將產⽣⼀個

不同的結果。max巨集可以證明具有副作⽤的引數所引起的問題。

可以用linux指令檢視一下它的與處理結果

即它在進行選擇時對y又進行了一次++

故y++執行了兩次最後結果為10,其實比並不符合我們預期的結果故max巨集可以證明具有副作⽤的引數所引起的問題。

3、理解編譯鏈結整個過程和詳細的每個過程

從c語言轉換成機器能夠識別的二進位制需要如下幾個過程

預處理(巨集替換,去注釋,標頭檔案按照路徑展開,條件編譯)-->編譯-->彙編-->鏈結

以這個程式為例

#define max(a, b)  ((a) > (b) ? (a) : (b))

#include

int main()

~          

先來看預處理之後的結果:使用gcc -e www.c -o ww.i 和vim.i指令

接下來進行編譯使用gcc -s www.i -o www.s 和vim.s指令

接下來在進行彙編使用gcc -c www.s -o www.o 和vim www.o指令

最後是鏈結過程採用gcc www.o -o www 和vim www指令

C 主流預處理,編譯和鏈結過程

在c 的程式的編寫過程中,基本上都碰到過lnk2005的錯誤吧,下面就針對這個問題詳細分析 首先,預處理階段 這一過程,主要針對 include和 define進行處理,具體過程如下 對於cpp檔案中經常會出現 include來包含某個標頭檔案,在進行預處理之後,所有的 include命令都將替換成...

程式編譯,鏈結過程

c語言的編譯鏈結過程要把我們編寫的乙個c程式 源 轉換成可以在硬體上執行的程式 可執行 需要進行編譯和鏈結。編譯就是把文字形式源 翻譯為機器語言形式的目標檔案的過程。鏈結是把目標檔案 作業系統的啟動 和用到的庫檔案進行組織形成最終生成可載入 可執行 的過程。過程 如下 預處理器 將.c 檔案轉化成 ...

程式的編譯鏈結過程

一段源 到可執行性程式需要經歷預處理 編譯彙編和鏈結等步驟,接下來詳細介紹這些過程 假設檔案main.czhong有如下 include int main 1 巨集定義指令 2 條件編譯 3 標頭檔案包含指令 4 特殊符號處理 不能在標頭檔案中定義全域性變數,因為在標頭檔案中定義全域性變數將會使所有...