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
这样就全部都注释掉了。
预处理还有很多其他扩展语法,不过大部分时候,我们知道这三个就够了。