一、预处理
1、编译预处理
C语言允许在程序中使用几种特殊的命令(它们不是一般的C语句),在C编译系统对程序进行通常的编译之前,先对程序中这些特殊命令进行“预处理”,然后将预处理的结果和源程序一起再进行通常的编译处理,以得到目标代码。所以预处理不占用系统运行的时间。
2、主要预处理功能
(1)宏定义 ;
(2)文件包含;
(3)条件编译
二、宏定义
1、概念
(1)宏:是对正文进行代入或嵌入的一种功能。即从一字符流中取出某个字符串去代替源程序里的标识符。
说明:
①宏名使用大小写字母都可以,习惯用大写字母,以便与变量名相区别;
②宏名用做代替一个字符串,不作语法检查;
③宏定义不是C语句,不要以";“结尾,否则把”;"也作为字符串内容一起替换;
④宏定义的有效范围为定义之处到#undef命令终止,如果没有#undef命令,则有效范围到本文结束;
⑤在进行宏定义时,可以引用已定义的宏名;这时将层层替换。
⑥宏定义不能递归:
⑦C语言允许宏定义出现在程序中函数外面的任何位置,但一般情况下它总写在文件的开头。
(2)宏替换(宏展开) :用宏内容(字符串)原样代换程序中的所有宏名字的过程
说明:
①宏替换由编译程序预先进行;不占运行时间 。
②宏替换范围是除字符串以外的所有宏名字;
③若替换后文本串中仍含有宏名字,将再次进行替换,直到程序中不含宏名字为止。
2、宏两种常见形式:
(1)不带参形式。
#define 标识符 字符串 //用标识符来代表一个字符串。
#define PI 3.1415926f 标识符PI代表“3.1415926”
#include <stdio.h>
#define PI 3.1415926
#define STR "hello world"
void main()
{
float l,s,r,v;
printf("请输入半径:");
scanf("%f",&r);
l=2.0*PI*r;
s=PI*r*r;
v=3.0/4*PI*r*r*r;
printf("周长=%8.2f\n面积=%8.2f\n体积v=%8.2f\n",l,s,v);
printf("%s\n",STR);
}
(2)带参形式。
#define FUNCTION(x) ((x)*(x))
例1:
//#define 宏名(宏形参数表) 字符串 //宏替换时以实参数替代形参数。
#include <stdio.h>
#define PI 3.1415926
#define S(r) PI*r*r
void main()
{
float a=3.6,area;
area=S(a); //S(a)用PI*a*a替换
printf("a=%f area=%f\n",a,area);
}
输出:
a=3.600000 area=40.715038
例2:
#include <stdio.h>
#define FC(x) x*x
//#define FC(x) (x)*(x)
//#define FC(x) ((x)*(x))
void main()
{
int a=2,b=3, c;
c=FC(a+b)/FC(a+1);
printf("c=%d\n",c);
}
按第一种宏定义:c=a+b*a+b/a+1*a+1;
按第二种宏定义:c=(a+b)*(a+b)/(a+1)*(a+1);
按第三种宏定义:c=((a+b)*(a+b))/((a+1)*(a+1));
例3:
#define SWAP(x,y) x>y?x:y
void main()
{
int x=3,y=2,c;
c=SWAP(x,y);
printf("c=%d\n",c);
}
三、“文件包含”处理
“文件包含“:是指一个源文件可以将另外一个源文件的全部内容包含进来。
C语言提供#include命令来实现“文件包含”的操作,其一般形式为:
#include “文件名” 或 #include <文件名>
作用:使编译系统把指定的被包含文件嵌入到带有#include的源文件中。
#include “文件名”:自定义函数文件
先在当前工作目录中去查找,若找不到再到指定的标准目录中去查找。适合包含用户自己编辑的.C文件。
#include <文件名>:库函数
直接到系统指定的标准目录中去查找。适合包含系统头文件。
四、条件编译
根据条件选择被编译的源程序行。
1、使用宏定义的标识符作为编译条件
满足条件(条件表达式的值非零)的代码参加编译,否则不参加编译。
(1)当所指定的标识符已经被#define 命令定义过,则在程序编译阶段只编译程序段1,否则编译程序段2。
# ifdef 标识符 //如果定义了...
程序段1
# else
程序段2
#endif
示例:
#include <stdio.h>
#if X==3
#define Y 3
#else
#define Y 5
#endif
int main()
{
printf("%d\n", Y);
return 0;
}
(2)当所指定的标识符已经被#define 命令定义过,则在程序编译阶段只编译程序段1。
# ifdef 标识符
程序段1
#endif
(3)当所指定的标识符未被#define 命令定义过,则在程序编译阶段只编译程序段1,否则编译程序段2。
# ifndef 标识符 //如果没有定义...
程序段1
# else
程序段2
#endif
(4)其他形式
#elif // 否则如果...
#undef // 取消定义,和#define相反
2、使用常量表达式的值作为编译条件
当所指定的表达式为真(非零)时就编译程序段1,否则编译程序段2。
# if 表达式
程序段1
# else
程序段2
#endif
编辑 2020-09-13 04:28 首次编辑
增改 2021-07-04 20:25 内容结构优化
注:本文旨于作为自己的学习笔记,不作他用。