C 预处理器和宏
本文讨论了 C 语言中的预处理器,并通过实例介绍了 #include
、#define
和条件编译。
在 C 程序被编译之前,需要一些处理工作,比如引入头文件等。 C 语言定义了一些指令来完成这些工作,比如 #include
、#define
,这些指令被称为预处理器。
C 预处理器是编译之前的预处理步骤,这包括包含头文件,宏定义,条件编译等。整个过程可以简单的理解为一个文本替换的过程。比如包含头文件,预处理器简单的将头文件的源文件替换到此位置后,然后才进行编译。
所有预处理指令都以 #
符号开头。例如,
#define PI 3.14
C 预处理器的一些常见用途是:
- 包含头文件
- 定义宏
- 条件编译
使用 #include 包含头文件:
#include
预处理器用来包含头文件到 C 程序。例如,
#include <stdio.h>
这里, stdio.h
是一个头文件。#include
预处理器指令用来包含 stdio.h
头文件中的内容到当前文件中。
这就是为什么您需要先使用 #include <stdio.h>
,然后才能使用 scanf()
和 printf()
之类的函数的原因。
您还可以创建自己的包含函数声明的头文件,并使用 #include
预处理器指令将其包含在您的程序中。
#include "my_header.h"
使用 #define 定义宏
宏是给定名称的代码片段。您可以使用 #define
预处理器指令在 C 中定义宏。
如下示例:
#define c 299792458 // 光速
在这里,当我们在我们的程序中使用 c
时,它被替换为 299792458
.
示例 1:宏定义
#include <stdio.h>
#define PI 3.1415
int main()
{
float radius, area;
printf("Enter the radius: ");
scanf("%f", &radius);
// Notice, the use of PI
area = PI * radius * radius;
printf("Area=%.2f",area);
return 0;
}
宏定义函数
除了上面的宏定义,我们可以使用宏定义函数。宏定义函数调用方式和函数类似。例如,
#define circleArea(r) (3.1415*(r)*(r))
程序每次遇到 circleArea(argument)
,就用 (3.1415*(argument)*(argument))
替换。
假设,我们将 5
作为参数传递给宏定义函数,那么 circleArea(5)
被替换为 (3.1415*5*5)
。
示例 2:宏定义和宏定义函数
#include <stdio.h>
#define PI 3.1415
#define circleArea(r) (PI*r*r)
int main() {
float radius, area;
printf("Enter the radius: ");
scanf("%f", &radius);
area = circleArea(radius);
printf("Area = %.2f", area);
return 0;
}
条件编译
在 C 语言编程中,您可以指示预处理器是否包含代码块。为此,可以使用条件指令。
它类似于 if
声明,但又有一个主要区别:
if
在执行期间测试该语句以检查是否应执行代码块,而条件编译用于在执行之前的编译阶段确定是否包含或跳过某个代码块。
条件编译的用途
- 根据机器、操作系统使用不同的代码
- 在两个不同的程序中编译相同的源文件
- 从程序中排除某些代码,但保留它作为将来的参考
如何使用条件编译?
使用 #ifdef
, #if
, #defined
, #else
和 #elseif
指令来进行条件编译。
#ifdef 指令
#ifdef MACRO
// 条件代码
#endif
这里,条件代码仅在 MACRO
被定义的情况下才包含在程序中。
#if、#elif 和 #else 指令
#if expression
// 条件代码
#endif
这里, expression
是整数类型的表达式(可以是整数、字符、算术表达式、宏等)。
条件代码仅在 expression
的结果为非零值的情况下才包含在程序中。
可选 #else
指令可以与 #if
指令一起使用。
#if expression
// 如果表达式结果不为 0,包含此处的代码
#else
// 如果表达式结果为 0,包含此处的代码
#endif
您还可以将嵌套条件 #elif
添加到 #if...#else
中间:
#if expression
// 如果 expression 结果不为 0,包含此处的代码
#elif expression1
// 如果 expression1 结果不为 0,包含此处的代码
#elif expression2
// 如果 expression2 结果不为 0,包含此处的代码
#else
// 如果所有表达式结果为 0,包含此处的代码
#endif
defined
特殊运算符 defined
用于测试是否定义了某个宏。它经常用在 #if
指令中。
#if defined BUFFER_SIZE && BUFFER_SIZE >= 2048
// codes
预定义宏
以下是 C 语言编程中的一些预定义宏。
宏 | 说明 |
---|---|
__DATE__ |
表示当前编译日期的字符串 |
__FILE__ |
表示当前文件名的字符串 |
__LINE__ |
表示当前行号的整数 |
__STDC__ |
如果遵循 ANSI 标准 C,则该值为非零整数 |
__TIME__ |
表示当前编译时间的字符串 |
示例 3:获取当前编译时间
以下程序使用 __TIME__
宏输出当前编译时间。
#include <stdio.h>
int main()
{
printf("Current time: %s",__TIME__);
}
输出
Current time: 19:54:39