一、預處理
gcc -E xx.c------> 生成 .i 文件
進行預處理工作 不會自動生成文件
工作內容:
① 宏替換、頭文件導入、條件編譯等
② 去掉注釋內容
二、編譯
gcc -S xx.i ------->生成匯編程序 .s
檢查語法錯誤 生成匯編程序
工作內容:
檢查源代碼或者經過預處理之后代碼的語法錯誤
三、匯編
gcc -c xx.s ------->生成目標文件 .o
工作內容:
把匯編代碼匯編成目標文件(二進制) 其實是用as命令
四、鏈接
gcc xx.o ------>生成可執行程序a.out
鏈接一個或者多個目標文件生成可執行程序 默認是a.out 其實是用ld命令
工作內容:鏈接函數調用
gcc *.o 鏈接所有的目標文件 生成 可執行程序
-o 可以指定目標文件名字
注意:
語法錯誤檢查:在編譯階段
函數調用檢查:在鏈接階段
預處理指令
在預處理階段就會進行處理的指令
以#開頭的指令
一、#include 包含頭文件
導入頭文件中的代碼
調用了標准庫的函數時需要導入頭文件
#include <> 與 #include ""的區別
<> 從系統指定的路徑(可配置)搜索包含的頭文件
"" 從當前目錄搜索包含的頭文件,
如果在當前目錄下沒有找到,則去系統指定的目錄下搜索
如果是包含自己寫的頭文件時用"",包含標准庫的一般用<>
二、#define
宏名 一般用大寫字母
1.宏定義 在預處理階段進行簡單的宏替換
#define PI 3.14
2.宏函數
#define POW(x) ((x)*(x))
預處理階段不進行運算 只進行替換
注意:不要在宏定義后面加上 ;
宏函數需要給每個參數都加上小括號 以及最后整體加上小括號 避免產生歧義
宏函數和參數列表之間不能有額外的空格
3. \ 可以連接宏定義
一般而言 宏只能放在一行 但是可以通過 \ 來連接多行 作為同一個宏定義
4. # 可以把一個標識符變成一個字面值字符串
#define TOSTR(x) #x
#define print(x) printf(#x"=%d\n",x)
5. ## 可以生成新的標識符
6.宏的作用:
① 方便修改
② 簡化編程
③ 參數沒有類型限制 靈活
7.宏可以在代碼中用 #define 定義,也可以在編譯時用 -D 宏名稱 來定義宏
三、條件編譯
分支選擇語句 只有當執行時才確定執行哪一個分支 會把兩個分支的語句都編譯到代碼中去
編譯時 可以選擇 編譯的代碼
#if 根據宏的值來進行條件編譯
#elif
#else #否則
#endif #條件編譯結尾
#ifdef #if defined 如果定義了某個宏 用宏是否定義來進行條件編譯
#ifndef 如果沒有定義某個宏
#undef 刪除一個宏 取消宏定義
#ifdef/#ifndef/#if defined #endif //宏是否定義來進行條件編譯
#if /#elif #endif //宏的值來進行條件編譯
頭文件衛士:
用於防止多次引用該頭文件
如果不加 程序稍微復雜一些就可能引發重復定義的錯誤
#ifndef XXX_H__
#define XXX_H__
#endif //XXX_H__