- C语言编程教程
- C语言 - 首页
- C语言基础
- C语言 - 概述
- C语言 - 特性
- C语言 - 历史
- C语言 - 环境搭建
- C语言 - 程序结构
- C语言 - Hello World
- C语言 - 编译过程
- C语言 - 注释
- C语言 - 词法单元
- C语言 - 关键字
- C语言 - 标识符
- C语言 - 用户输入
- C语言 - 基本语法
- C语言 - 数据类型
- C语言 - 变量
- C语言 - 整数提升
- C语言 - 类型转换
- C语言 - 类型强制转换
- C语言 - 布尔值
- C语言中的常量和字面量
- C语言 - 常量
- C语言 - 字面量
- C语言 - 转义序列
- C语言 - 格式说明符
- C语言中的运算符
- C语言 - 运算符
- C语言 - 算术运算符
- C语言 - 关系运算符
- C语言 - 逻辑运算符
- C语言 - 位运算符
- C语言 - 赋值运算符
- C语言 - 一元运算符
- C语言 - 自增和自减运算符
- C语言 - 三元运算符
- C语言 - sizeof 运算符
- C语言 - 运算符优先级
- C语言 - 其他运算符
- C语言中的决策语句
- C语言 - 决策语句
- C语言 - if 语句
- C语言 - if...else 语句
- C语言 - 嵌套 if 语句
- C语言 - switch 语句
- C语言 - 嵌套 switch 语句
- C语言中的循环语句
- C语言 - 循环语句
- C语言 - while 循环
- C语言 - for 循环
- C语言 - do...while 循环
- C语言 - 嵌套循环
- C语言 - 无限循环
- C语言 - break 语句
- C语言 - continue 语句
- C语言 - goto 语句
- C语言中的函数
- C语言 - 函数
- C语言 - 主函数
- C语言 - 按值调用函数
- C语言 - 按引用调用函数
- C语言 - 嵌套函数
- C语言 - 可变参数函数
- C语言 - 用户自定义函数
- C语言 - 回调函数
- C语言 - 返回语句
- C语言 - 递归
- C语言中的作用域规则
- C语言 - 作用域规则
- C语言 - 静态变量
- C语言 - 全局变量
- C语言中的数组
- C语言 - 数组
- C语言 - 数组的特性
- C语言 - 多维数组
- C语言 - 将数组传递给函数
- C语言 - 从函数返回数组
- C语言 - 变长数组
- C语言中的指针
- C语言 - 指针
- C语言 - 指针和数组
- C语言 - 指针的应用
- C语言 - 指针运算
- C语言 - 指针数组
- C语言 - 指向指针的指针
- C语言 - 将指针传递给函数
- C语言 - 从函数返回指针
- C语言 - 函数指针
- C语言 - 指向数组的指针
- C语言 - 指向结构体的指针
- C语言 - 指针链
- C语言 - 指针与数组
- C语言 - 字符指针和函数
- C语言 - 空指针
- C语言 - void 指针
- C语言 - 野指针
- C语言 - 解引用指针
- C语言 - 近指针、远指针和巨型指针
- C语言 - 指针数组的初始化
- C语言 - 指针与多维数组
- C语言中的字符串
- C语言 - 字符串
- C语言 - 字符串数组
- C语言 - 特殊字符
- C语言中的结构体和联合体
- C语言 - 结构体
- C语言 - 结构体和函数
- C语言 - 结构体数组
- C语言 - 自引用结构体
- C语言 - 查找表
- C语言 - 点 (.) 运算符
- C语言 - 枚举 (enum)
- C语言 - 结构体填充和压缩
- C语言 - 嵌套结构体
- C语言 - 匿名结构体和联合体
- C语言 - 联合体
- C语言 - 位域
- C语言 - typedef
- C语言中的文件处理
- C语言 - 输入/输出
- C语言 - 文件 I/O (文件处理)
- C语言预处理器
- C语言 - 预处理器
- C语言 - 编译指示
- C语言 - 预处理器操作符
- C语言 - 宏
- C语言 - 头文件
- C语言中的内存管理
- C语言 - 内存管理
- C语言 - 内存地址
- C语言 - 存储类
- 其他主题
- C语言 - 错误处理
- C语言 - 可变参数
- C语言 - 命令执行
- C语言 - 数学函数
- C语言 - static 关键字
- C语言 - 随机数生成
- C语言 - 命令行参数
- C语言编程资源
- C语言 - 问答
- C语言 - 快速指南
- C语言 - 速查表
- C语言 - 有用资源
- C语言 - 讨论
C语言预处理器操作符
预处理器操作符是在#define指令的上下文中使用的特殊符号。这些操作符也称为预处理器专用操作符。
在C语言中,定义了一组预处理器操作符,每个操作符都附带一个重要的操作。本章将解释在C语言中使用的不同类型的预处理器操作符。
大多数现代C编译器都实现了以下预处理器操作符:
操作符 | 作用 |
---|---|
续行操作符 (/) | 用于续接过长的宏。 |
字符串化操作符 (#) | 将对应的实际参数用双引号括起来。 |
标记粘贴操作符 (##) | 允许将用作实际参数的标记连接起来以形成其他标记。 |
defined 操作符 | 简化在某些宏指令中编写复合表达式的过程。 |
现在让我们详细讨论每个预处理器操作符。
续行操作符 (/)
当宏非常复杂且跨越多行时,使用此操作符。如果宏展开中的逻辑很复杂,则需要换行并编写跨越多行的代码。在这种情况下,宏续行操作符非常有用。
示例1:预处理器续行操作符 (/)
在下面的示例中,我们在下一行编写宏的一部分,因此我们使用了宏续行预处理器操作符 (\)。
#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
示例2:预处理器续行操作符 (/)
在下面的示例中,宏定义涉及 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
字符串化操作符 (#)
有时您可能希望将宏参数转换为字符串常量。“数字符号”或“字符串化”操作符 (#) 将宏参数转换为字符串字面量,而不展开参数定义。此操作符只能用于具有指定参数列表的宏。
示例1:字符串化操作符
请看下面的例子:
#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"
示例2:字符串化操作符
以下代码展示了如何使用**字符串化操作符**将某些文本转换为字符串,而无需使用任何引号。
#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
标记粘贴操作符 (##)
双数字符号或标记粘贴操作符 (**##**),有时称为合并操作符。它通常用于在展开宏时将两个标记合并为一个。
当宏展开时,每个“**##**”操作符两侧的两个标记将组合成一个标记,然后在宏展开中用该标记替换“**##**”和这两个原始标记。
示例1:标记粘贴操作符 (##)
请看下面的例子:
#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
示例2:标记粘贴操作符 (##)
在下面的示例中,我们将两个参数传递给宏。
#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
defined 操作符
defined 预处理器操作符只能用作**#if**和**#elif**指令的一部分。defined 操作符的语法如下:
#if defined(macro1) // code #elif defined(macro2) // code #endif
它用于在常量表达式中确定是否定义了标识符。如果定义了指定的标识符,则值为真(非零)。如果未定义该符号,则值为假(零)。
示例1:defined 操作符
在此示例中,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.
示例2:defined 操作符
以下代码检查 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