一、定义
程序设计领域中,预处理一般是指在程序源代码被翻译为目标代码的过程中,生成二进制代码之前的过程。典型地,由预处理器(preprocessor) 对程序源代码文本进行处理,得到的结果再由编译器核心进一步编译。这个过程并不对程序的源代码进行解析,但它把源代码分割或处理成为特定的单位——(用C/C++的术语来说是)预处理记号(preprocessing token)用来支持语言特性(如C/C++的宏调用)。
(版权:Baidu百科)
二、例子
(刚刚学完说明文十大说明方法,那就举几个栗子)
#include <iostream>
#pragma commect(lib, "ws2_32.lib")
#if 1
#define ABCDEFG 0
#else
#define ABCDE 0
#endif
看出来了吗?
对,预处理并不是那么复杂,其实“#”开头就是预处理(字符串除外)
三、宏
听起来很高大上是吧?
其实不然。
在 C++中,宏分为 有参数和无参数两种。无参宏的宏名后不带参数,其定义的一般形式为:
#define 标识符 字符串;
其中“#”表示这是一条预处理命令“define”为宏定义命令,“标识符”为所定义的宏名, “字符串”可以是常数、表达式、格式串等。符号常量的定义就是一种无参宏定义。
此外,常常对程序中反复使用的表达式进行宏定义。
#define M (y*y+3*y);
它的作用是指定标识符 M 来代替表达式(y*y+3*y)。
在编写源程序时, 所有的(y*y+3*y)都可由 M 代替, 而对源程序进行编译时,将先由预处理程序进行宏代换,即用(y*y+3*y)表达式去置换所有的宏名 M,然后 再进行编译。
C++允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对于带 参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。
带参宏定义的一般形式为:
#define 宏名(形参表) 字符串;
在字符串中含有各个形参。
带参宏调用的一般形式为:
宏名(实参表);
例如:
#define M(y) y*y+3*y
//宏定义
//......
k=M(5);//宏调用
易错点:
看如下代码:
#include <iostream>
using namespace std;
#define Add(x, y) x + y
int main()
{
int x, y;
cin >> x >> y;
cout << (double)(Add(x, y) / 2);
return 0;
}
这很简单,就是求平均数,对吗?
看看输入输出样例:
【输入1】10 20
【输出1】20
【输入2】15 30
【输出2】30
【输入3】0 1
【输出3】0.5
这又是怎么回事呢?
由于宏其实是直接替换的,所以——
看看样例1,其实相当于:
#include <iostream>
using namespace std;
#define Add(x, y) x + y
int main()
{
int x, y;
cin >> x >> y;//输入:x=10,y=20
cout << (double)x + y / 2;
return 0;
}
看出破绽了吗?
对,宏并不会帮我们计算x+y,而是直接替换。
所以宏尽量加上括号
那么,#if 0又是怎么回事呢?
#if 0相当于多行注释/**/,但调式代码方便。
例如一段完整的代码:
#include <iostream>
using namespace std;
#if 1
int main()
{
cout << "Hello,World!";//输出你好世界(Hello,World)
}
#else
int main()
{
cout << "Hello,Universe";//输出你好宇宙
}
#endif
如果想输出Hello,World!就这样;
想输出Hello,Universe只需把1改为0即可,而不用费劲的把两个注释去了,而且——
#include <iostream>
using namespace std;
int main()
{
cout << "Hello,World!";//输出你好世界(Hello,World)
}
/*
int main()
{
cout << "Hello,Universe";/*输出你好宇宙*/
}
*/
像这种注释连注释的多了去了,But #if 0则不会这样,谁没事乱写#endif呢?而且绝对不编译错误。