Cprogramming 简明教程
Preprocessors in C
C 预处理器不是编译器的一部分,而是编译过程中的一个单独步骤。简单来说,C 预处理器只是一个文本替换工具,它指示编译器在实际编译之前执行所需的预处理。我们称 C 预处理器为 CPP。
The C Preprocessor is not a part of the compiler, but is a separate step in the compilation process. In simple terms, a C Preprocessor is just a text substitution tool and it instructs the compiler to do the required pre-processing before the actual compilation. We’ll refer to the C Preprocessor as CPP.
在 C 编程中, preprocessing 是 C 代码编译的第一步。它发生在 tokenization 步骤之前。预处理器的主要功能之一是包含 header files ,其中包含程序中使用的库函数。C 中的预处理器还定义常量和扩展宏。
In C programming, preprocessing is the first step in the compilation of a C code. It occurs before the tokenization step. One of the important functions of a preprocessor is to include the header files that contain the library functions used in the program. The preprocessor in C also defines the constants and expands the macros.
C 中的预处理器语句称为 directives 。程序的预处理器部分始终出现在 C 代码的顶部。每个预处理器语句都以哈希 (#) 符号开头。
The preprocessor statements in C are called directives. A preprocessor section of the program always appears at the top of the C code. Each preprocessor statement starts with the hash (#) symbol.
Preprocessor Directives in C
下表列出了所有重要的预处理程序指令:
The following table lists down all the important preprocessor directives −
Directive |
Description |
# define |
Substitutes a preprocessor macro. |
#include |
Inserts a particular header from another file. |
#undef |
Undefines a preprocessor macro. |
#ifdef |
Returns true if this macro is defined. |
#ifndef |
Returns true if this macro is not defined. |
#if |
Tests if a compile time condition is true. |
#else |
The alternative for #if. |
#elif |
#else and #if in one statement. |
#endif |
Ends preprocessor conditional. |
#error |
Prints error message on stderr. |
#pragma |
Issues special commands to the compiler, using a standardized method. |
Preprocessors Examples
分析以下示例以了解各种指令。
Analyze the following examples to understand various directives.
此 #define 指令告诉 CPP 将 MAX_ARRAY_LENGTH 的实例替换为 20。使用 #define 以增加常量的可读性。
This #define directive tells the CPP to replace the instances of MAX_ARRAY_LENGTH with 20. Use #define for constants to increase readability.
#define MAX_ARRAY_LENGTH 20
以下指令告诉 CPP 从系统库中获取“stdio.h”并将文本添加到当前源文件中。下一行告诉 CPP 从本地目录获取“myheader.h”并将内容添加到当前源文件中。
The following directives tell the CPP to get "stdio.h" from the System Libraries and add the text to the current source file. The next line tells CPP to get "myheader.h" from the local directory and add the content to the current source file.
#include <stdio.h>
#include "myheader.h"
现在,来看一下以下 #define 和 #undef 指令。它们告诉 CPP 取消定义现有的 FILE_SIZE 并将其定义为 42。
Now, take a look at the following #define and #undef directives. They tell the CPP to undefine existing FILE_SIZE and define it as 42.
#undef FILE_SIZE
#define FILE_SIZE 42
以下指令告诉 CPP 仅在 MESSAGE 尚未定义时定义 MESSAGE。
The following directive tells the CPP to define MESSAGE only if MESSAGE isn’t already defined.
#ifndef MESSAGE
#define MESSAGE "You wish!"
#endif
以下指令告诉 CPP 处理在 DEBUG 定义时括起来的语句。
The following directive tells the CPP to process the statements enclosed if DEBUG is defined.
#ifdef DEBUG
/* Your debugging statements here */
#endif
如果在编译时将 -DDEBUG 标志传递给 gcc 编译器,这很有用。这将定义 DEBUG,以便您可以在编译期间随时打开和关闭调试。
This is useful if you pass the -DDEBUG flag to the gcc compiler at the time of compilation. This will define DEBUG, so you can turn debugging ON and OFF on the fly during compilation.
Predefined Macros in C
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
让我们尝试以下示例:
Let’s try the following example −
#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: 13:32:30
Line: 8
ANSI: 1
Preprocessor Operators
C 预处理器提供以下运算符来帮助创建宏:
The C preprocessor offers the following operators to help create macros −
Example: The Macro Continuation (\) Operator in C
宏通常限制在一行中。宏延续运算符 (\) 用于继续一行中过长的宏。请看以下示例:
A macro is normally confined to a single line. The macro continuation operator (\) is used to continue a macro that is too long for a single line. Take a look at the following example −
#include <stdio.h>
#define message_for(a, b) \
printf(#a " and " #b ": We love you!\n")
int main() {
message_for(Ram, Raju);
}
当你运行这段代码时,它将产生以下输出:
When you run this code, it will produce the following output −
Ram and Raju: We love you!
Example: The Stringize (
字符串化运算符(#),也称为井号运算符,在宏定义中使用时,会将宏参数转换为字符串常量。
The stringize operator (#), also called number-sign operator, when used within a macro definition, converts a macro parameter into a string constant.
字符串化运算符只能在具有指定参数或参数列表的宏中使用。例如:
The stringize operator may be used only in a macro having a specified argument or parameter list. For example −
#include <stdio.h>
#define message_for(a, b) \
printf(#a " and " #b ": We love you!\n")
int main() {
message_for(Carole, Debra);
return 0;
}
运行代码并检查其输出:
Run the code and check its output −
Carole and Debra: We love you!
Example: The Token Pasting (
宏定义中的标记粘贴运算符 (##)将两个参数组合起来。它允许多个宏定义中的标记加入到单独的标记中。例如:
The token-pasting operator (##) within a macro definition combines two arguments. It permits two separate tokens in the macro definition to be joined into a single token. For example −
#include <stdio.h>
#define tokenpaster(n) printf ("token" #n " = %d", token##n)
int main() {
int token34 = 40;
tokenpaster(34);
return 0;
}
当你运行这段代码时,它将产生以下输出:
When you run this code, it will produce the following output −
token34 = 40
Example: The defined() Operator in C
预处理器定义的运算符用于常量表达式中,以确定标识符是否使用 #define 定义。如果指定了标识符,则值为 true(非零)。如果未定义符号,则值为 false(零)。
The preprocessor defined operator is used in constant expressions to determine if an identifier is defined using #define. If the specified identifier is defined, the value is true (non-zero). If the symbol is not defined, the value is false (zero).
以下示例显示如何在 C 程序中使用 defined operator :
The following example shows how you can use the defined operator in a C program −
#include <stdio.h>
#if !defined (MESSAGE)
#define MESSAGE "You wish!"
#endif
int main() {
printf("Here is the message: %s\n", MESSAGE);
return 0;
}
运行代码并检查其输出:
Run the code and check its output −
Here is the message: You wish!
Parameterized Macros in C
CPP强大的功能之一是使用参数化宏模拟函数的能力。例如,我们可能有一些代码如下平方一个数字:
One of the powerful functions of the CPP is the ability to simulate functions using parameterized macros. For example, we might have some code to square a number as follows −
int square(int x) {
return x * x;
}
我们可以使用以下宏重写上述代码:
We can rewrite above the code using a macro as follows −
#define square(x) ((x) * (x))
具有参数的宏必须在使用之前使用 #define 指令进行定义。参数列表用圆括号括起来,并且必须紧跟宏名称。宏名称和左括号之间不允许有空格。
Macros with arguments must be defined using the #define directive before they can be used. The argument list is enclosed in parentheses and must immediately follow the macro name. Spaces are not allowed between the macro name and open parenthesis.
Example
以下示例演示如何在 C 中使用参数化宏:
The following example demonstrates how you can use parameterized macros in C −
#include <stdio.h>
#define MAX(x,y) ((x) > (y) ? (x) : (y))
int main() {
printf("Max between 20 and 10 is %d\n", MAX(10, 20));
return 0;
}
当你运行这段代码时,它将产生以下输出:
When you run this code, it will produce the following output −
Max between 20 and 10 is 20