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 - Main 函数 C - 按值调用函数 C - 按引用调用函数 C - 嵌套函数 C - 可变参数函数 C - 用户定义函数 C - 回调函数 C - return 语句 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 - 指针 vs 数组 C - 字符指针和函数 C - NULL 指针 C - void 指针 C - 悬垂指针 C - 解引用指针 C - Near、Far 和 Huge 指针 C - 指针数组的初始化 C - 指针与多维数组

C 语言中的字符串

C - 字符串 C - 字符串数组 C - 特殊字符

C 语言的结构体和联合

C - 结构体 C - 结构体和函数 C - 结构体数组 C - 自引用结构 C - 查找表 C - 点 (.) 运算符 C - 枚举(或 enum) C - 结构填充和打包 C - 嵌套结构 C - 匿名结构和联合 C - 联合 C - Bit 位字段 C - Typedef

C 语言中的文件处理

C - 输入和输出 C - 文件 I/O(文件处理)

C 语言中的预处理器

C - 预处理器 C - #pragma 编译指示 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 编译器都实现了以下预处理运算符 -

运算符 操作
继续运算符 (/) 用于继续一行内容过长的宏。
字符串化运算符 (#) 将相应的实际参数括在双引号中
标记粘贴运算符 (##) 允许使用标记作为实际参数连接起来形成其他标记
定义运算符 简化某些宏指令中复合表达式的编写

现在让我们详细讨论一下这些预处理运算符。

延续运算符 (/)

此运算符用于宏非常复杂且跨越多行的情况。如果宏扩展内部逻辑复杂,则需要断行并编写跨越多行的代码。在这种情况下,宏延续运算符非常有用。

示例 1:预处理延续运算符 (/)

在下面的示例中,我们将在下一行编写宏的一部分,因此我们使用了宏延续预处理运算符 (\)。

#include <stdio.h>

#define  message() { \
   printf("TutorialsPoint Library contains
"); \
   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
"); break; \  
   case 2: printf("2. RECTANGLE
"); break; \  
   case 3: printf("3. SQUARE
"); break; \  
   default: printf("default. LINE
"); \  
} 

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 "
")

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
", PASTE(value_,1));
}

输出

运行此代码时,将产生以下输出 -

value_1 = 1000

示例 2:标记粘贴运算符 (##)

在下面的示例中,我们向宏传递了两个参数。

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

int main() {

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

输出

运行此代码时,将产生以下输出 -

value1: 1220
value2: 1230

defined 运算符

defined 预处理运算符只能作为 #if#elif 指令的一部分使用。defined 运算符的语法如下:-

#ifdefined(macro1)
// code
#elifdefined(macro2)
// code
#endif

它用于常量表达式中,用于判断标识符是否已定义。如果指定的标识符已定义,则值为 true(非零)。如果符号未定义,则值为 false(零)。

示例 1:defined 运算符

在此示例中,defined 运算符用于检查 DEBUG 宏是否已定义。如果已定义,则程序打印"DEBUG mode is on"。否则,它会打印"DEBUG 模式已关闭"。

#include <stdio.h>

#define DEBUG 1

int main() {

   #if defined(DEBUG)
   printf("DEBUG mode is on.
");
   #else
      printf("DEBUG mode is off.
");
   #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