预处理器

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 之间的内容不会执行。

  

以上是关于预处理器的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段6——CSS选择器

如何从该片段中的 onItemSelectedListener 中获取微调器单击的项目?

片段着色器中设置的颜色未显示 GLSL 1.30

片段着色器究竟如何用于纹理?

纹理上的片段着色器

持久片段和查看器