预处理器指令(Preprocessor directives)
预处理指令
预处理指令是程序代码中前面带有哈希符号(#)的行
注意:
- 预处理器在代码实际编译之前检查代码,并在生成实际代码之前解析所有指令。
- 预处理器指令仅扩展到一行代码,不用分号结尾
- 预处理器指令可扩展到多行的唯一方法是在行尾换行符前加上反斜杠(\)
宏定义(macro definitions)(#define,#undef)
使用#define定义预处理器宏,语法为
#define identifier replacement
预处理器会将代码其余部分的任何identifier转为replacement
#define还可以使用参数来定义函数宏:
#define getmax(a,b) a>b?a:b
我们所定义的宏不受块结构的影响,宏会一直持续到#undef预处理器指令为止。
宏定义接受替换序列中的两个特殊字符(#和##)
-
运算符#
将#后的参数名所包含的参数,由包含参数的字符串文字替换(就像是由双引号括起来一样)
-
运算符##
运算符##连接两个参数,它们之间不留空格
由于预处理器替换发生在任何C++语法检查之前,因此宏定义可能是一个棘手的功能。但是,要小心:严重依赖复杂宏的代码变得不那么可读,因为预期的语法在许多情况下与程序员在C++中期望的正常表达式不同。
条件包含(Conditional inclusions)(#ifdef,#ifndef,#if,#endif,#else and#elif)
这些指令允许在满足特定条件时包括或者抛弃部分代码
#ifdef仅在指定为参数的宏已定义时才会编译,无论它的值是什么
#ifdef TABLE_SIZE
int table[TABLE_SIZE];
#endif
在这部分代码中,当TABLE_SIZE在之前被#define定义后才会执行,如果未定义,则该行将不会包含在程序编译中。
#ifndef用于完全相反的情况下,#ifndef与#endif之间的指令只在没有进行过定义时,才会进行编译。
#ifndef TABLE_SIZE
#define TABLE_SIZE 100
#endif
int table[TABLE_SIZE];
#if,#else,#elif(“else if”)要满足某些条件才会编译,#if和#elif之后只能计算常量表达式
#if TABLE_SIZE>200
#undef TABLE_SIZE
#define TABLE_SIZE 200
#elif TABLE_SIZE<50
#undef TABLE_SIZE
#define TABLE_SIZE 50
#else
#undef TABLE_SIZE
#define TABLE_SIZE 100
#endif
int table[TABLE_SIZE];
行控制(#line)
当我们编译程序并在编译过程中发生一些错误时,编译器会显示一条错误消息,其中包含对发生错误的文件名的引用和行号,因此更容易找到生成错误的代码
#line 20 "assigning variable"
int a?;
此代码将生成一个错误,该错误将在文件 第 20 行中显示为"assigning variable"错误
#error
此指令会在它被找到时停止编译,生成可指定为其参数的错误
#ifndef __cplusplus
#error A C++ compiler is required!
#endif
如果未定义宏名__cplusplus(默认情况下,所有C++编译器都定义了此宏名),则本示例中止编译过程。
#include
两种形式
- #include<>
- #include""
#pragma
此指令用于向编译器指定各种选项。这些选项特定于您使用的平台和编译器。有关可以使用 定义的可能参数的详细信息,请参阅手册或编译器的参考。
#pragma once
为了避免同一个头文件被包含(include)多次
#pragma once 一般由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。
#pragma endregion和#pragma region
visual中的预处理命令,折叠指定代码块
预定义的宏名称
名 | 含义 |
---|---|
__LINE__ | 表示正在编译的源代码文件中的当前行的整数值。 |
__FILE__ | 一个字符串文本,包含正在编译的源文件的假定名称。 |
__DATE__ | 一个字符串文本,格式为“Mmm dd yyyy”,包含编译过程开始的日期。 |
__TIME__ | 格式为“hh:mm:ss”的字符串文本,包含编译过程开始的时间。 |
__cplusplus | 整数值。所有C++编译器都将此常量定义为某个值。其值取决于编译器支持的标准版本: 199711L : ISO C++ 1998/2003**201103L **: ISO C++ 2011不合格的编译器将此常量定义为最多五位数的某个值。请注意,许多编译器并不完全符合要求,因此将此常量定义为上述值中的任何一个。 |
__STDC_HOSTED__ | 1 如果实现是托管实现(具有所有可用的标准标头), 则为非本机。0 |
名 | 含义 |
---|---|
__STDC__ | 在 C: 中,如果定义为 ,则实现符合 C 标准。 在C++:已定义实现。1 |
__STDC_VERSION__ | 在 C 语言中: 199401L :ISO C 1990,修订 1**199901L : ISO C 1999201112L **: ISO C 2011在C++:已定义实现。 |
__STDC_MB_MIGHT_NEQ_WC__ | 1 如果多字节编码可能会在字符文本中为字符提供不同的值 |
__STDC_ISO_10646__ | 格式为 的值,指定 Unicode 标准的日期,后跟字符的编码yyyymmL``wchar_t |
__STDCPP_STRICT_POINTER_SAFETY__ | 1 如果实现具有严格的指针安全性(请参见get_pointer_safety ) |
__STDCPP_THREADS__ | 1 如果程序可以有多个线程 |