预处理器是不聪明,不懂C++语法;相反,它只处理文本之前,编译器运行。然后,预处理器的输出发送到编译器。
包括
你已经看到了# include指令在行动。当你#包括文件,预处理器复制包含文件为包括在#点文件包含指令的内容。当您有需要被包含在多个地方的信息(如前向声明通常是)时,这是有用的。
的#包括命令有两种形式:
#包括<文件名>告诉预处理器要找的文件在一个特别的地方,由操作系统的C++运行时库的头文件举行。你通常会使用这种形式当你包括头文件来编译(例如,C++标准库的一部分)。
#包括“文件名”告诉预处理器寻找含源文件做#目录文件包括。如果它没有找到头文件,它会检查任何其他包括你指定你的编译器和IDE设置部分路径。该失败,它将采取相同的倾斜括号的情况下。您通常会使用此表单,包括您自己的头文件。
宏定义
的#指令可以用来创建宏。宏是一个规则,它定义了一个输入序列(例如一个标识符)如何被转换成一个替换的输出序列(例如,一些文本)。
有两种基本类型的宏:类的宏和函数类的宏。
函数像宏功能,并有类似的功能。我们不会讨论他们,因为他们的使用通常被认为是危险的,几乎所有的东西,他们可以做的(内联)功能。
像宏一样的对象可以用两种方法中的一种:
#定义标识符
# substitution_text定义标识符
上面的定义没有替换文本,而最下面的定义是。因为这些都是预处理程序声明(不是语句),注意不能形成以分号结束。
带有替换文本的对象的宏
当处理器遇到这个指令,再发生“标识”是由“substitution_text”。该标识符是传统上键入的所有大写字母,使用下划线表示空格。
这种形式的宏像你可能预期的工作:任何进一步发生的标识符被删除,取而代之的是什么!
这可能看起来很没用,它是用于做文本替换的。然而,这并不是这个指令的形式通常用于。我们将在一瞬间讨论这种形式的用途。
与替代文本的宏不同的对象,这种形式的宏通常被认为是可以接受的使用。
条件编译
条件编译预处理指令允许您指定在什么条件下会或不会编译。唯一的条件编译指令我们要在这段盖# # ifdef,ifndef,和# endif。
的# ifdef预处理指令允许处理器检查值是否已#定义。如果是这样的话,编译# ifdef和相应的# endif之间的代码。如果不是,代码将被忽略。
考虑下面的代码片段:
#定义print_joe
# ifdef print_joe
std::cout <<“乔”<< std::endl;
# endif
# ifdef print_bob
std::cout <<“鲍伯”<< std::endl;
# endif
因为print_joe已经#定义,行cout <<“乔”<< endl;将编译。因为print_bob尚未#定义,行cout <<“鲍伯”<< endl;将不会编译。
#则是# ifdef相反,它允许你检查是否一个名字尚未定义。
#则print_bob
std::cout <<“鲍伯”<< std::endl;
# endif
该程序打印的“鲍伯”,因为print_bob从未#定义。
有条件编译是用相当一点的形式的头卫士。我们将看看下一节课的那些。
现在你可能会想:
#定义print_joe
# ifdef print_joe
/ /…
由于我们定义的print_joe是什么,怎么来的预处理器没有替换print_joe在# ifdef print_joe没有?宏只导致正常代码的文本替换。其它预处理命令都被忽略。因此,在# ifdef print_joe的print_joe独自。