预处理命令
源程序中以#开头的行称为预处理指令。
预处理指令并不是C语言的语法成分,而是传给编译程序的指令。
包括:
宏定义
#define
#undef
文件包含
#include
条件编译
#if
#ifdef
#else
#elif
#endif
其他
#line
#error
#pragma
在这里我们浅谈一下宏定义。
宏定义
#define指令定义一个标识符来代表一个字符串,这种标识符称为宏名,在源程序中发现该标识符时,都用该字符串替换,这种操作叫做宏替换,是在预编译的时候进行的。
不带参数的宏定义
直接看代码体会一下。
代码语言:javascript复制#include <iostream>
#define a cout<<r*r*3.14<<" "<<2*3.14*r
using namespace std;
int main(void)
{
int r;
cin>>r;
a;
}
它相当于下面这个代码。
代码语言:javascript复制#include <iostream>
using namespace std;
int main(void)
{
int r;
cin>>r;
cout<<r*r*3.14<<" "<<2*3.14*r;
}
就是输入圆的半径,求面积和周长。
初学者一般喜欢这样用宏定义。
代码语言:javascript复制#include <iostream>
#define P 3.14
using namespace std;
int main(void)
{
int r;
cin>>r;
cout<<r*r*P<<" "<<2*P*r;
}
简单来说,宏定义就是直接替换字符串,而不对文本做任何处理。基于这样的前提,以后出现的各种问题都可以找到解释。
注意,宏没有分号结尾,除非你故意加分号,让这个分号成为替换的字符串的一部分。
宏取消
宏名的作用域是从定义开始直到所在的文件结束,如果需要终止宏,可以使用#undef命令。
代码语言:javascript复制#define N 666
……
#undef N
带参数的宏定义
先看代码体会一下。
代码语言:javascript复制#include <iostream>
#define max(a,b) (((a)>(b))?(a):(b))
using namespace std;
int main(void)
{
int a,b;
cin>>a>>b;
cout<<max(a,b);
}
带参数的宏与函数看起来非常像,也被称为类函数宏。
但是这两个是不一样的。
就像你看上面这个代码的宏定义,是不是用了很多括号,如果a和b只是单单的一个变量而不是一堆复杂的表达式,是不用这么多括号的,因为宏定义仅仅只是简单的字符替换,就是把标识符后面的字符串简单替换标识符。