首先熟悉一些預處理識別符號
__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 特殊符號處理 不能在標頭檔案中定義全域性變數,因為在標頭檔案中定義全域性變數將會使所有...