编译预处理是对C语言源程序编译前进行的预加工,这些操作是通过命令来实现的,即预编译命令,主要有三种,即宏定义、文件包含和条件编译。这些规定是由编译系统规定的,由于不是C语言本身的组成部分,因此不能直接编译,而要经过编译器预处理再与源程序进行编译 书写规则:#+关键字(一行书写一个)
用一个指定的标识符(名字)来代表一个字符串。
格式:#define 标识符 字符串 用标识符来代替字符串,在程序中出现宏名的位置,经过编译器的处理,被替换成对应的宏字符串,称为宏展开。标识符又称为宏名,通常用大写字母来表示,字符串称为宏体,一般是常数、关键词、语句、表达式等,也可以是空白,末尾不用分号。宏名的有效范围是从定义命令开始到程序结束,通常写在程序的开头,比如#define PI 3.1415926 根据源程序中出现PI用3.1415926来替换
#include <stdio.h>
#define PI 3.1415926
int main()
{
float r = 6;
float l,s,v;
l = 2.0 * PI * r;
s = PI*r*r;
v = 4.0/3*PI*r*r*r;
printf("r = %.2f\nl = %.2f\ns = %.2f\nv = %.2f\n",r,l,s,v);
}宏展开只是简单的用定义的宏体替换宏名,由于是替换,所以宏定义中有无圆括号效果是不同的
比如
#define W 80
#define L W+40
#define S L*W
int main()
{
printf("L = %d\nW = %d\nS = %d\n",L,W,S);
}如果没有括号那么S将会被替换成80+40*80 很明显是不对的,所以需要用圆括号 另外在printf内,双引号中的LWS没有被替换,仅替换不在双引号以内的,制作字符串替换,并不会分配和占用内存。
\#define 标识符(形参表) 字符串 其中字符串包含形参参数,一般为表达式,也可以包括宏名和函数。使用带参宏时候,一定要注意要用实参替换形参。 宏展开通过宏体替换宏名(直接置换宏定义命令中相应的形参字符串,非形参字符保持不变)
#define V(l,w,h) l*w*h
...
VOLUME = v(4,2,8);经过宏展开之后,赋值语句为4*2*8 按照宏定义的形参表的顺序从左向右进行置换,对于非形参字符*保留 带参数的宏定义中也可以引用已定义的宏定义
#define PI 3.1415926
#define S(r) PI*r*r
#define V(r) 4.0/3*S(r)*r预处理是对每个宏名进行展开替换,直到程序中不再有宏名为止,我们来试着宏展开一下 假设V(3) = 4.0/3*S(3)*3 V(3) = 4.0/3*PI*3*3*3 V(3) = 4.0/3*3.1415926*3*3*3 宏替换中的实参广义上是一个字符串,一般为常量、变量或表达式。所以V的实参可以为(3*a)等 当然也可以用函数定义,带参数的宏和函数虽有很多相似之处,但二者在本质是不一样的。

条件编译 一般情况下,源程序中的所有语句都参加编译,但是我们有时会需要满足某种条件时才被编译。 条件编译命令格式 \#ifdef 标识符 程序段1 \#else 程序段2 \#endif 若标识符已被定义过,则编译程序1否则编译程序2 \#if 标识符 程序段1 \#else 程序段2 \#endif 若指定表达式的值为真,则程序段1参加编译,否则程序段2参加编译 \#ifndef 程序段1 \#else 程序段2 \#endif 若标识符未被定义,则编译程序段1,否则编译程序段2