什么?你还不知道什么是C++ 预处理器?看这一篇就够了~
目录
C++ 预处理器
#define 预处理
参数宏
条件编译
和 ## 运算符
C++ 中的预定义宏
最后知识点
写在最后
C++ 预处理器
预处理器是一些指令,指示编译器在实际编译之前所需完成的预处理。
所有预处理指令都以井号符号(#)开头,并且在执行这些操作时仅允许前后出现空格字符。这些指令并非典型的C++语句类型,并因此不会被标记为需要结束于分号符号(;)。
我们观察到,在各个实例中都包含了 #include 指令。这个宏的作用是将头文件导入到源文件中。
除了C++的标准库之外,它还提供了一系列强大的预处理功能。以下是一些常见的预处理指令:像 #include 用于包含头文件、#define 用于宏定义、#if 用于条件编译等。我们一起来了解一下这些关键工具的用法吧!
#define 预处理
#define 预处理指令的作用是负责创建符号常量,并在编程环境中扮演重要角色。所使用的符号常量通常被称为宏 ,在编程中被广泛使用,并且具有特定的表示形式。
每当某个特定的代码行包含在一个文件中时,在编译阶段之前,该文件中的所有宏都会被替换成指定的 text。例如
#include <iostream>
using namespace std;
#define PI 3.14159
int main ()
{
cout << "Value of PI :" << PI << endl;
return 0;
}
AI助手
请我们现在对这段代码进行测试以观察预处理后的结果 假设源代码文件已存在 我们将使用 -E 选项来进行编译 并将其输出重定向至test.p文件中 一旦查看test.p文件内容时 您将发现它已经包含大量详细信息 并且在尾部部分的数值已经被修改为以下内容:
...
int main ()
{
cout << "Value of PI :" << 3.14159 << endl;
return 0;
}
AI助手
参数宏
您可以使用 #define 来定义一个带有参数的宏,如下所示:
#include <iostream>
using namespace std;
#define MIN(a,b) (a<b ? a : b)
int main ()
{
int i, j;
i = 100;
j = 30;
cout <<"较小的值为:" << MIN(i, j) << endl;
return 0;
}
AI助手
当上面的代码被编译和执行时,它会产生下列结果:
条件编译
存在一组指令能够根据特定条件选择性地处理部分代码块。
这一技术被称作条件编译。
条件预处理器的结构与 if 选择结构很像。请看下面这段预处理器的代码:
您可以只在调试时进行编译,调试开关可以使用一个宏来实现,如下所示:
当指令 #ifdef DEBUG 在执行前已经定义了符号常量 DEBUG时,则会触发对程序中 cerr 的编译操作。采用 #if 0 语句来注释掉程序的一部分,请参考以下示例:
让我们尝试下面的实例:
#include <iostream>
using namespace std;
#define DEBUG
#define MIN(a,b) (((a)<(b)) ? a : b)
int main ()
{
int i, j;
i = 100;
j = 30;
#ifdef DEBUG
cerr <<"Trace: Inside main function" << endl;
#endif
#if 0
cout << MKSTR(HELLO C++) << endl;
#endif
cout <<"The minimum is " << MIN(i, j) << endl;
#ifdef DEBUG
cerr <<"Trace: Coming out of main function" << endl;
#endif
return 0;
}
AI助手
当上面的代码被编译和执行时,它会产生下列结果:
# 和 ## 运算符
和 ## 预处理运算符在C++语言及ANSI/ISO C标准中均为可应用的工具。它们负责将 replacement-text 标识符转换成带引号的字符串形式。
请看下面的宏定义:
#include <iostream>
using namespace std;
#define MKSTR( x ) #x
int main ()
{
cout << MKSTR(HELLO C++) << endl;
return 0;
}
AI助手
当上面的代码被编译和执行时,它会产生下列结果:
让我们来看看它是如何工作的。不难理解,C++ 预处理器把下面这行:
转换成了:
运算符用于连接两个令牌。下面是一个实例:
在程序运行过程中,当出现CONCAT指令时,在某些编程环境中(如QBASIC),它会将给定的参数连接起来,并将这些连接后的结果用于替代宏变量或直接生成字符串。比如,在程序中使用CONCAT(HELLO, C++)会替换成字符串'HELLO C++'。如以下示例所示:
#include <iostream>
using namespace std;
#define concat(a, b) a ## b
int main()
{
int xy = 100;
cout << concat(x, y);
return 0;
}
AI助手
当上面的代码被编译和执行时,它会产生下列结果:
让我们来看看它是如何工作的。不难理解,C++ 预处理器把下面这行:
转换成了:
C++ 中的预定义宏
C++ 提供了下表所示的一些预定义宏:
| 宏 | 描述 |
|---|---|
| LINE | 这会在程序编译时包含当前行号。 |
| FILE | 这会在程序编译时包含当前文件名。 |
| DATE | 这会包含一个形式为 month/day/year 的字符串,它表示把源文件转换为目标代码的日期。 |
| TIME | 这会包含一个形式为 hour:minute:second 的字符串,它表示程序被编译的时间。 |
让我们看看上述这些宏的实例:
> 1. #include <iostream>
>
> 2. using namespace std;
>
> 3.
>
> 4. int main ()
>
> 5. {
>
> 6. cout << "Value of __LINE__ : " << __LINE__ << endl;
>
> 7. cout << "Value of __FILE__ : " << __FILE__ << endl;
>
> 8. cout << "Value of __DATE__ : " << __DATE__ << endl;
>
> 9. cout << "Value of __TIME__ : " << __TIME__ << endl;
>
> 10.
>
> 11. return 0;
>
> 12. }
>
>
>
>
> AI助手
当上面的代码被编译和执行时,它会产生下列结果:
最后知识点
# 和 ## 运算符
在字符串化处理中使用#符号,在宏定义中将后续参数转换为字符串。
在作为字符串化操作使用时,
其主要功能是将宏参数直接转换为不进行扩展的字符串常量。
宏定义参数左右两边的空格会被忽略,
各个 Token 之间的多个空格会被转换成一个空格。
含有特殊含义字符如'或\时,
这些字符前面会自动被添加上转义字符 \。
连接符号,把参数连在一起。
将多个 Token 连接成一个 Token。要点:
- 它不能是宏定义中的第一个或最后一个 Token。
- 前后的空格可有可无。
该文档详细阐述了各种基本数据类型及其对应用途,并明确了变量在程序中的声明与赋初过程。涵盖整数类型、浮点数类型、字符类型以及指针类型的定义;同时涉及变量声明与初始化的过程。这些内容为后续算法实现奠定了必要的基础条件。
该段文字已经按照要求进行了改写
控制语句 包括条件语句、循环语句、跳转语句等。
函数及其参数的传递机制 包括以下几方面:首先涉及函数的定义域与值域;其次探讨具体输入输出变量之间的关系;最后详细阐述参数的具体传输途径以及具体的实现手段。特别地,在这一过程中具体包括参数的接收与发送机制以及相应的处理逻辑。值得注意的是,在数据处理过程中具体采用的方式包括但不限于:基于值的数据传输与基于指针的数据传输策略。
数组与指针涉及的内容包括:对数组的定义说明、对数组元素的操作处理、高维(多维)数组的概念及其特点、对指针进行的操作运算等详细说明。
字符串处理 包括字符串的定义、字符串常见操作(比较、复制、连接、分割等)。
文件操作 包括文件打开、读取、写入、关闭等常用操作。
内存管理 包括动态内存分配函数malloc和free的使用。
写在最后
最近流量越来越少,求求大家给个关注,收藏呗,谢谢啦
