预处理器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了预处理器相关的知识,希望对你有一定的参考价值。
本文是对C++预处理器的学习整理,参考了网站www.learncpp.com相关章节的内容。
一、概述
代码在编译之前需要通过预处理器进行预处理,预处理器运行时,逐行扫描代码寻找预处理指令。预处理指令是以#开头、换行符结尾(不是分号;)的代码。
预处理器主要实现一下三个功能:
1. include
2. macro define 宏定义。
3. 条件编译
二、include
故名思意,#include用于包含头文件,预处理器在遇到#include 指令时,将相应头文件的内容复制到指令所在的位置。一般,将函数的声明放在头文件里面,这样通过包含头文件可以在代码中实现变量的声明。
主要有两种形式:#include <filename> 或者 #include "filename"。
#include <filename> 形式: 用于包含系统目录中头文件,告诉预处理器在系统目录中查找C++ runtime library 的头文件。
#include "filename" 形式: 用于包含用户自定义的头文件,首先在代码文件所在目录中查找,如果不存在则在IDE设置的包含目录中查找,若不存在再在系统目录中查找。
#include <filename>
tells the preprocessor to look for the file in a special place defined by the operating system where header files for the C++ runtime library are held. You’ll generally use this form when you’re including headers that come with the compiler (e.g. that are part of the C++ standard library).
#include "filename"
tells the preprocessor to look for the file in directory containing the source file doing the #include. If it doesn’t find the header file there, it will check any other include paths that you’ve specified as part of your compiler/IDE settings. That failing, it will act identically to the angled brackets case. You’ll generally use this form for including your own header files.
三、宏定义
主要由两种形式,有替换文字和无替换文字。
#define identifier
#define identifier substitution_text
第一种无文字替换的形式,主要用于头文件保护(header guards),防止由于重复包涵头文件造成的重复定义,下面再讲。
第二种用于文字替换,如进行某些常量的处理。
#define MY_FAVORITE_NUMBER 9
std::cout << "My favorite number is: " << MY_FAVORITE_NUMBER << std::endl; //此处,预处理器 将 MY_FAVORITE_NUMBER 替换为9
四、条件编译
主要为三条指令:#ifdef, #ifndef, and #endif。
在如下代码中,会输出"Joe", 而"Bob"不会输出。
#define PRINT_JOE #ifdef PRINT_JOE std::cout << "Joe" << std::endl; #endif #ifdef PRINT_BOB std::cout << "Bob" << std::endl; #endif
同样, #ifndef XXX 含义为当XXX未被预定义时编译相关代码。
前面提到 header guards ,主要用法为:
1 #ifndef XXXX_H 2 #define XXXX_H 3 4 //头文件内容 5 //当同在一个cpp文件内,多次包含同一个头文件时,相当于把头文件内容多次复制到cpp文件内,会造成多次声明同一个变量,造成编译错误。 6 //使用header guards 可以避免选择性编译,避免重复声明。 7 8 #endif
五、预处理指令的作用范围
在文件编译之前,预处理器逐文件逐行的扫面文件,预处理一个文件之后,该文件内的预处理指令全部被清除。因此,预处理指令指在文件内有效,当预处理器逐行扫描文件结束,则预处理器预定义的量失效。比如在 file.cpp中 #define XXXX,再main.cpp中 #ifdef XXXX #endif 之间的内容不会执行。
以上是关于预处理器的主要内容,如果未能解决你的问题,请参考以下文章