Cprogramming 简明教程

Macros in C

Macros in C 是给予特定常数值或代码语句的名称,它们在编译前处理器之前用它们的值/代码替换。 C Macros 使用 #define 预处理程序指令来定义。

Macros in C are the names given to specific constant values or code statements which are replaced with their value/code before the compilation processor. C Macros are defined using the #define preprocessor directive.

Macros 对于代码重用、定义常量、定义内联函数和条件编译很有用。

Macros are useful for code reusability, defining constant values, defining inline functions, and conditional compilations.

以下是本教程中我们将涵盖的不同类型的 C 宏 –

The following are the different types of C macros that we are going to cover in this tutorial –

  1. Object-like Macros

  2. Function-like Macros

  3. Chained Macros

  4. Variadic Macros

  5. Predefined Macros

Object-like Macros

定义常量的宏是类对象宏。

A macro that defines a constant is an object-like macro.

Syntax

它使用以下语法完成 −

It is done with the following syntax −

#define name value

Example of Object-like Macros

在下面的示例中,我们正在定义一个类对象宏 −

In the following example, we are defining an object-like macro −

#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;
}

Function-like Macro

要定义一个类函数宏,您使用相同的“#define”指令,但在宏名称后面立即使用一对括号,并带有一个或多个参数。这种宏仅当它的名称后面出现一对括号时才展开。

To define a function-like macro, you use the same "#define" directive, but you put a pair of parentheses immediately after the macro name, with one or more arguments. Such a macro is expanded only when its name appears with a pair of parentheses after it.

当预处理器扩展这种宏时,它将替换文本中的指定参数相结合。类似函数的宏经常被称作带参数(或变量)的宏。

When the preprocessor expands such a macro, it incorporates the specified arguments in the replacement text. The function-like macros are often called Macros with parameters (or arguments).

Syntax

类似函数的宏被定义如下 −

A function-like macro is defined as follows −

#define macro_name([parameter_list]) replacement_text

Example of Function-like Macros

下面是类似函数的宏的一个例子 −

An example of function-like macro is given below −

#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;
}

当你运行这段代码时,它将产生以下输出:

When you run this code, it will produce the following output −

x: 5 	Square of x: 25

Rules for Defining Function-like Macros

定义函数的一些规则也适用于宏 −

Some rules of defining a function also apply to macros −

  1. A macro can be defined without arguments

  2. A macro can be defined with a fixed number of arguments

  3. A macro can be defined with a variable number of arguments

例如,当您使用这种宏时,逗号分隔的参数列表必须包含与宏定义中的参数一样多的参数。

For example, when you use such a macro, the comma-separated argument list must contain as many arguments as there are parameters in the macro definition.

Function-like Macros without Arguments

类似函数的宏也可以在没有参数的情况下定义。

A function-like macro may also be defined without arguments.

Example 1

下面这个例子展示了你如何使用一个没有参数的宏 −

The following example shows how you can use a macro without arguments −

#include <stdio.h>

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

int main() {

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

运行代码并检查其输出:

Run the code and check its output −

Hello World

一些标准库在其中也提供了宏定义。例如, getchar() 宏在扩展时,按照以下方式实现了 getc() 函数 −

Some standard libraries also provide macro definitions in it. For example, the getchar() macro when expanded, implements the getc() function as follows −

#define getchar() getc(stdin)

同样, putchar() 宏封装了 putc() 函数 −

Similarly, the putchar() macro encapsulates the putc() function −

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

Example 2

下面的程序定义了一个名为 LOOP(x) 的宏,并且将 for 循环运行与它的参数次数一样多 −

The following program defines a macro named as LOOP(x) and runs a for loop for the number of times as its argument −

#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);
}

当你运行这段代码时,它将产生以下输出:

When you run this code, it will produce the following output −

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

Chained Macros

当我们有一个宏嵌套在另一个宏内部时,它们被称为链接宏。

When we have a macro nested inside another macro, they are called Chained Macros.

Example of Chained Macros

下面的例子展示了你如何使用链接宏 −

The following example shows how you can use chained macros −

#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;
}

当你运行这段代码时,它将产生以下输出:

When you run this code, it will produce the following output −

Circumference of a circle with radius 5 is 31.420000

Variadic Macros

您还可以使用数量不确定的参数或可变参数的宏来定义一个宏。具有可变长度参数的宏是一种使宏能够接受任何数量参数的功能。您可以将位置参数以及关键字参数传递给一个宏。

You can also define a macro with variable number of arguments or variadic macros. A macro with variable-length argument is a feature that enables a macro to accept any number of arguments. You can pass positional as well as keyword arguments to a macro.

在定义可变参数宏时,省略号(…)作为参数给出以获取数量不确定的参数。为了使用可变参数宏,省略号可以被指定为宏定义中的最后一个形式参数。令牌的这个序列将替换宏体中标识符 VA_ARGS 无论它出现在哪里。

When a variadic macro is defined, the ellipsis (…) is given as an argument to capture variable number of arguments. To use variadic macros, the ellipsis may be specified as the final formal argument in a macro definition. This sequence of tokens replaces the identifier VA_ARGS in the macro body wherever it appears.

VA_ARGS 将被与省略号匹配的所有参数替换,包括它们之间的逗号。请注意,可变参数宏只能在 C99 兼容的 C 编译器及以上版本中使用。

The VA_ARGS is replaced by all of the arguments that match the ellipsis, including commas between them. Note that the variadic macros can be used only in the C99 compatible C compilers and above.

Example of Variadic Macros

请看以下示例:

Take a look at the following example −

#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;
}

运行代码并检查其输出:

Run the code and check its output −

2
2

Predefined Macros

ANSI C 定义了许多宏。虽然每个宏都可用在编程中,但是预定义的宏不应该直接被修改。

ANSI C defines a number of macros. Although each one is available for use in programming, the predefined macros should not be directly modified.

Macro

Description

DATE

The current date as a character literal in "MMM DD YYYY" format.

TIME

The current time as a character literal in "HH:MM:SS" format.

FILE

This contains the current filename as a string literal.

LINE

This contains the current line number as a decimal constant.

STDC

Defined as 1 when the compiler complies with the ANSI standard.

Example

以下示例演示如何在 C 程序中使用预定义宏 −

The following example demonstrates how you can use the predefined macros in a C program −

#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__ );
}

当你运行这段代码时,它将产生以下输出:

When you run this code, it will produce the following output −

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