Cprogramming 简明教程

Preprocessor Operators in C

Preprocessor operators 是在 #define 指令上下文中使用的特殊符号。这些运算符也称为预处理器特定运算符。

在 C 中,已定义了一组预处理器运算符,每个运算符都附带了一个重要的操作。在本章中,我们将解释 C 中使用的不同类型的预处理器运算符。

以下预处理器运算符已由大多数现代 C 编译器实现:

Operator

Action

Continuation operator (/)

用于继续对于一行而言过长的宏。

Stringizing operator (#)

导致相应的实际参数括在双引号中

Token-pasting operator (##)

允许用作实际参数的标记连接以形成其他标记

defined operator

简化了在特定宏指令中编写复合表达式

现在让我们详细讨论这些预处理器运算符中的每一个。

Continuation Operator (/)

在宏非常复杂且跨越多行的情况下使用此运算符。在宏扩展内部存在复杂逻辑的情况下,你将需要换行并编写跨越多行的代码。在这种情况下,宏继续运算符非常有用。

Example 1: Preprocessor Continuation Operator (/)

在下面的示例中,我们在下一行中编写宏的一部分,因此我们正在利用宏继续预处理器运算符 (\)。

#include <stdio.h>

#define  message() { \
   printf("TutorialsPoint Library contains\n"); \
   printf("High quality Programming Tutorials"); \
}

int main() {

   message();
   return 0;
}

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

TutorialsPoint Library contains
High quality Programming Tutorials

Example 2: Preprocessor Continuation Operator (/)

在以下示例中,宏定义包括对 switch case 语句的求值,因此跨越多行,需要宏继续字符。

#include <stdio.h>

#define SHAPE(x) switch(x) { \
   case 1: printf("1. CIRCLE\n"); break; \
   case 2: printf("2. RECTANGLE\n"); break; \
   case 3: printf("3. SQUARE\n"); break; \
   default: printf("default. LINE\n"); \
}

int main() {

   SHAPE(1);
   SHAPE(2);
   SHAPE(3);
   SHAPE(0);
   return 0;
}

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

1. CIRCLE
2. RECTANGLE
3. SQUARE
default. LINE

Stringizing Operator (

有时可能需要将宏参数转换为字符串常量。数字符号或“字符串化”运算符 (#) 将宏参数转换为字符串文字,而不展开参数定义。此运算符只能在具有指定参数列表的宏中使用。

Example 1: Stringizing Operator

请看以下示例:

#include <stdio.h>
#define stringize(x) printf(#x "\n")

int main() {

   stringize(Welcome To TutorialsPoint);
   stringize("The Largest Tutorials Library");
   stringize("Having video and Text Tutorials on Programming Languages");
}

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

Welcome To TutorialsPoint
"The Largest Tutorials Library"
"Having video and Text Tutorials on Programming Languages"

Example 2: Stringizing Operator

以下代码展示了如何使用 stringize operator 将某些文本转换为字符串,而不使用任何引号。

#include <stdio.h>
#define STR_PRINT(x) #x

main() {
   printf(STR_PRINT(This is a string without double quotes));
}

运行代码并检查其输出:

This is a string without double quotes

Token Pasting Operator (

双数字符号或标记粘贴运算符 ( ## ),有时称为合并或组合运算符。在扩展宏时经常将两个标记合并为一个很有用。

当扩展一个宏时,“ ”运算符两侧的两个标记都将组合成一个标记,然后用此标记在宏扩展中替换“ ”和两个原始标记。

Example 1: Token Pasting Operator (

请看以下示例:

#include <stdio.h>

#define PASTE(arg1,arg2) arg1##arg2

main() {

   int value_1 = 1000;
   printf("value_1 = %d\n", PASTE(value_,1));
}

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

value_1 = 1000

Example 2: Token Pasting Operator (

在以下示例中,我们将两个参数传递给宏。

#include <stdio.h>
#define TOKENS(X, Y) X##Y

int main() {

   printf("value1: %d\n",TOKENS(12,20));
   printf("value2: %d\n",TOKENS(12,20)+10);
   return 0;
}

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

value1: 1220
value2: 1230

The defined Operator

定义的预处理程序运算符只能用作 #if#elif 指令的一部分。定义运算符的语法如下 −

#if defined(macro1)
// code
#elif defined(macro2)
// code
#endif

它用在常量表达式中,以确定标识符是否已定义。如果指定的标识符已定义,则值为真(非零)。如果符号未定义,则值为假(零)。

Example 1: defined Operator

在此示例中,使用 defined 运算符检查是否已定义 DEBUG 宏。如果已定义,则程序打印“DEBUG 模式已开启”。否则,它将打印“DEBUG 模式已关闭”。

#include <stdio.h>

#define DEBUG 1

int main() {

   #if defined(DEBUG)
   printf("DEBUG mode is on.\n");
   #else
      printf("DEBUG mode is off.\n");
   #endif

   return 0;
}

运行代码并检查其输出:

DEBUG mode is on.

Example 2: defined Operator

以下代码检查 square 宏是否已定义,如果已定义,则使用“x”的给定值(5)将其展开。

#include <stdio.h>

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

int main(){

   #if defined square
   printf("The square of the given number is: %d", square(5));
   #endif

   return 0;
}

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

The square of the given number is: 25