/

預處理器

預處理器

如何使用 C 預處理器

預處理器在 C 編程中非常有用,它是 C 標準的一部分,就像語言、編譯器和標準庫一樣。

它解析我們的程式並確保編譯器在繼續處理之前獲得所有所需的東西。

實際上它做了什麼呢?

例如,它查找所有使用 #include 指令包含的標頭文件。

它還查看您使用 #define 定義的所有常量並將其替換為其實際值。

這只是開始,我之前提到了這兩個操作,因為它們是最常見的操作。預處理器可以做更多的事情。

你有沒有注意到 #include#define 在開頭有個 #?這是所有預處理器指令的共同特點。如果一行以 # 開頭,那就是預處理器的事。

條件語句

我們可以使用條件語句來根據表達式的值來改變程式的編譯方式。

例如,我們可以檢查 DEBUG 常量是否為 0:

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

const int DEBUG = 0;

int main(void) {
#if DEBUG == 0
printf("I am NOT debugging\n");
#else
printf("I am debugging\n");
#endif
}

符號常量

我們可以定義一個符號常量:

1
2
3
#define VALUE 1
#define PI 3.14
#define NAME "Flavio"

當我們在程式中使用 NAME、PI 或 VALUE 時,預處理器會在執行程式之前用其值替換其名稱。

符號常量非常有用,因為我們可以為值命名,而不需要在編譯時創建變數。

巨集

使用 #define 也可以定義一個巨集。巨集和符號常量的區別在於巨集可以接受一個參數並通常包含程式碼,而符號常量只是一個值:

1
#define POWER(x) ((x) * (x))

注意參數周圍的括號,這是一種良好的實踐,可以避免在預編譯過程中替換巨集時出現問題。

然後我們可以在我們的程式中使用它,如下所示:

1
printf("%u\n", POWER(4)); //16

與函數的主要區別是宏不指定其參數或返回值的類型,這在某些情況下很方便。

如果定義了

我們可以使用 #ifdef 檢查一個符號常量或巨集是否被定義:

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#define VALUE 1

int main(void) {
#ifdef VALUE
printf("Value is defined\n");
#else
printf("Value is not defined\n");
#endif
}

我們還可以使用 #ifndef 來檢查相反的情況(巨集未定義)。

我們還可以使用 #if defined#if !defined 做相同的工作。

通常我們會用像這樣的代碼塊包裹一些代碼:

1
2
3
#if 0

#endif

暫時阻止其運行,或者使用 DEBUG 符號常量:

1
2
3
4
5
#define DEBUG 0

#if DEBUG
//僅當 DEBUG 不為 0 時,才將代碼發送給編譯器
#endif

預處理器還定義了一些您可以使用的預定義符號常量,其名稱前後的兩個下劃線表示,包括:

  • __LINE__ 轉換為源代碼文件的當前行
  • __FILE__ 轉換為文件的名稱
  • __DATE__ 轉換為編譯日期,格式為 Mmm gg aaaa
  • __TIME__ 轉換為編譯時間,格式為 hh:mm:ss

tags: [“C Preprocessor”, “conditionals”, “symbolic constants”, “macros”]