C語言中的宏



C語言中的宏是在編譯預處理器之前,為特定常量值或程式碼語句指定的名稱,並將其替換為其值/程式碼。C宏使用#define預處理器指令定義。

可用於程式碼重用、定義常量值、定義行內函數和條件編譯。

本教程將介紹以下不同型別的C宏:

  • 類物件宏
  • 類函式宏
  • 鏈式宏
  • 可變引數宏
  • 預定義宏

類物件宏

定義常量的宏稱為類物件宏。

語法

使用以下語法:

#define name value

類物件宏示例

在以下示例中,我們定義了一個類物件宏:

#include <stdio.h>

// Defining macros
#define PI 3.14
#define MAX 10

int main() {
   // Printing the values
   printf("Value of PI = %d\n", PI);
   printf("Value of MAX = %d\n", MAX);

   return 0;
}

類函式宏

要定義類函式宏,您使用相同的“#define”指令,但在宏名稱後立即新增一對括號,其中包含一個或多個引數。此類宏僅在其名稱後出現一對括號時才展開。

當預處理器擴充套件此類宏時,它會將指定的引數合併到替換文字中。類函式宏通常稱為帶引數(或自變數)的宏。

語法

類函式宏定義如下:

#define macro_name([parameter_list]) replacement_text

類函式宏示例

類函式宏的示例如下:

#include <stdio.h>

#define square(x) ((x) * (x))

int main(){

   int x = 5;
   printf("x: %d \tSquare of x: %d", x, square(x));
   return 0;
}

輸出

執行此程式碼時,將產生以下輸出:

x: 5 	Square of x: 25

定義類函式宏的規則

定義函式的一些規則也適用於宏:

  • 宏可以不帶引數定義
  • 宏可以帶固定數量的引數定義
  • 宏可以帶可變數量的引數定義

例如,當您使用此類宏時,逗號分隔的引數列表必須包含與宏定義中的引數一樣多的引數。

不帶引數的類函式宏

類函式宏也可以不帶引數定義。

示例1

以下示例演示瞭如何使用不帶引數的宏:

#include <stdio.h>

#define MESSAGE() printf("Hello World");

int main() {

   int x = 5;
   MESSAGE();
   return 0;
}

輸出

執行程式碼並檢查其輸出:

Hello World

一些標準庫也在其中提供了宏定義。例如,getchar()宏展開後,實現getc()函式如下:

#define getchar() getc(stdin)

同樣,putchar()宏封裝了putc()函式:

#define putchar(x) putc(x, stdout)

示例2

以下程式定義了一個名為LOOP(x)的宏,並根據其引數執行一個**for**迴圈:

#include <stdio.h>

#define LOOP(x) {\
   for (int i = 1; i <= x; i++)\
   printf("Iteration no: %d\n", i);\
}

int main() {

   int x = 3;
   LOOP(x);
}

輸出

執行此程式碼時,將產生以下輸出:

Iteration no: 1
Iteration no: 2
Iteration no: 3

鏈式宏

當一個宏巢狀在另一個宏中時,它們被稱為鏈式宏。

鏈式宏示例

以下示例演示瞭如何使用鏈式宏:

#include <stdio.h>

#define PI 3.142
#define CIRCUMFERENCE(x) (2*PI*x)

int main(){

   int x = 5;
   printf("Circumference of a circle with radius %d is %f", x, CIRCUMFERENCE(x));
   return 0;
}

輸出

執行此程式碼時,將產生以下輸出:

Circumference of a circle with radius 5 is 31.420000

可變引數宏

您還可以定義帶可變數量引數的宏或可變引數宏。帶可變長度引數的宏是一項功能,使宏能夠接受任意數量的引數。您可以將位置引數和關鍵字引數傳遞給宏。

定義可變引數宏時,省略號(…)作為引數傳遞以捕獲可變數量的引數。要使用可變引數宏,省略號可以指定為宏定義中的最後一個形式引數。此標記序列將替換宏體中出現的識別符號__VA_ARGS__。

__VA_ARGS__將被與省略號匹配的所有引數替換,包括它們之間的逗號。請注意,可變引數宏只能在C99相容的C編譯器及更高版本中使用。

可變引數宏示例

請檢視以下示例:

#include <stdio.h>

#define MAX_ARGS 5		// Define maximum number of allowed arguments
#define ARGS(x, ...) do {\
   printf("%d\n", ##__VA_ARGS__); \
} while (0)

int main() {

   ARGS(1, 2, 3); 		// 3 arguments
   ARGS(1, 2, 3, 4, 5, 6);	// 6 arguments 
   return 0;
}

輸出

執行程式碼並檢查其輸出:

2
2

預定義宏

ANSI C定義了許多宏。儘管每個宏都可用於程式設計,但不應直接修改預定義宏。

描述
__DATE__ 當前日期,以“MMM DD YYYY”格式的字元文字表示。
__TIME__ 當前時間,以“HH:MM:SS”格式的字元文字表示。
__FILE__ 包含當前檔名,以字串文字表示。
__LINE__ 包含當前行號,以十進位制常量表示。
__STDC__ 當編譯器符合ANSI標準時定義為1。

示例

以下示例演示瞭如何在C程式中使用預定義宏:

#include <stdio.h>

int main() {

   printf("File :%s\n", __FILE__ );
   printf("Date :%s\n", __DATE__ );
   printf("Time :%s\n", __TIME__ );
   printf("Line :%d\n", __LINE__ );
   printf("ANSI :%d\n", __STDC__ );
}

輸出

執行此程式碼時,將產生以下輸出:

File: main.c
Date: Mar 6 2024
Time: 20:12:19
Line: 8
ANSI: 1
廣告