Skip to content

Latest commit

 

History

History
107 lines (74 loc) · 2.74 KB

14.rst

File metadata and controls

107 lines (74 loc) · 2.74 KB
Authors: Kenneth Lee
Version: 0.1
Date: 2023-02-02
Status: Draft

预处理

这章介绍一下什么是预处理,你可以认为这是一种独立于C/C++的语言。

在C和C++的代码中,所有用#号开头的语句,都是“预处理”,它们不是C/C++基本语言的一 部分(但你也可以认为C/C++总是可以支持这种预处理的),换句话说,C/C++的编译器其 实是不处理这种语句的。但这些编译器会调用另一个程序,先把你的.cpp文件替换一下, 根据这种#开头的语句的要求,先把你的.cpp修改一下,然后才运行。

在gcc下,这个预处理程序叫做cpp,(C Pre-Processor)。比如你写这样一个程序::

// myfile.cpp
#define A 3
int a = A;

现在运行这个命令::

cpp myfile.cpp

你会看到这个结果:

# 0 "test.cpp" # 0 "<built-in>" # 0 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 0 "<command-line>" 2 # 1 "test.cpp"

int a = 3

#号开头的是cpp的注释,说明它干了什么,后面的是代码,这里的A,被换成了3。

这就是预处理的基本功能:帮你换掉你的代码。

所以,其实#include 也是一个预处理,它帮你把另外一个文件包含到你的文件里面来。你 甚至可以这样写::

// myfile.cpp
#define A 3
int a = A;
#include "我单独写的一个函数.txt"

这里也会无条件把你的文件包含进来,甚至都不需要是.cpp或者.h扩展名的。

预处理有简单的判断语句的语法。比如::

// myfile.cpp
#define A 3
#ifdef A
      int a = A;
#else
      int a = 0;
#endif

这个判断A有没有被定义过,如果有,就留下第一段代码,否则就留下第二段代码。

它也可以这样::

#define A 3
#ifndef A
      int a = 0;
#else
      int a = A;
#endif

这是反过来:如果没有定义A,就用第一段,否则就用第二段。你可以用cpp运行一下试一试

你还可以直接判断那个值本身,比如::

#define A 3
#if A
      int a = A;
#else
      int a = 0;
#endif

这是说,如果A是true(非零),就用第一段,否则用第二段。如果A干脆没有定义,这个 就是false。

if的这个特性,常常可以用来把一段代码注释掉。比如你有一段很长的代码,想临时关掉, 不让它执行,但你又不想删掉它,想一会儿再用。

一种办法当然是这样::

/*
... 要注释掉的代码
*/

但这种方法如果你中间有注释,就不行了。

所以更好的办法是这样的::

#if 0
...
#endif

这样就全部都注释掉了。

预处理还有很多其他扩展语法,不过大部分时候,我们知道这三个就够了。