|
C语言对源程序处理的四个步骤:预处理、编译、汇编、链接。预处理是在程序源代码被编译之前,由预处理器(Preprocessor)对程序源代码进行的处理。这个过程并不对程序的源代码语法进行解析,但它会把源代码分割或处理成为特定的符号为下一步的编译做准备工作。
1、文件包含指令(#include)
#incude<>和#include&#34;&#34;区别
- &#34;&#34; 表示系统先在file1.c所在的当前目录找file1.h,如果找不到,再按系统指定的目录检索。
- < > 表示系统直接按系统指定的目录检索。
注意:
- #include <>常用于包含库函数的头文件;
- #include &#34;&#34;常用于包含自定义的头文件;
- 理论上#include可以包含任意格式的文件(.c .h等) ,但一般用于头文件的包含;
2、宏定义
1 无参数的宏定义(宏常量)
#define num 100
在编译预处理时,将程序中在该语句以后出现的所有的num都用100代替。这种方法使用户能以一个简单的名字代替一个长的字符串,在预编译时将宏名替换成字符串的过程称为“宏展开”。宏定义,只在宏定义的文件中起作用。
说明:
- 宏名一般用大写,以便于与变量区别;
- 宏定义可以是常数、表达式等;
- 宏定义不作语法检查,只有在编译被宏展开后的源程序才会报错;
- 宏定义不是C语言,不在行末加分号;
- 宏名有效范围为从定义到本源文件结束;
- 可以用#undef命令终止宏定义的作用域;
- 在宏定义中,可以引用已定义的宏名;
2 带参数的宏定义(宏函数)
在项目中,经常把一些短小而又频繁使用的函数写成宏函数,这是由于宏函数没有普通函数参数压栈、跳转、返回等开销,可以调高程序的效率。
宏通过使用参数,可以创建外形和作用都与函数类似地类函数宏(function-like macro). 宏的参数也用圆括号括起来。
注意:
- 宏的名字中不能有空格,但是在替换的字符串中可以有空格。ANSI C允许在参数列表中使用空格;
- 用括号括住每一个参数,并括住宏的整体定义。
- 用大写字母表示宏的函数名。
- 如果打算宏代替函数来加快程序运行速度。假如在程序中只使用一次宏对程序的运行时间没有太大提高。
3 条件编译
一般情况下,源程序中所有的行都参加编译。但有时希望对部分源程序行只在满足一定条件时才编译,即对这部分源程序行指定编译条件。

用途:比如在限定部分运行时,比如debug和测试及发布版本的切换中使用。在使用visual Studio时会有颜色区分。
void test01()
{
#define MAX 1024
//#undef MAX
}
//3、 条件编译
//#define DEBUG
#ifdef DEBUG
void func()
{
printf(&#34;Debug版本发布\n&#34;);
}
#else
//自定义条件编译
#if 0
void func()
{
printf(&#34;Release1版本发布\n&#34;);
}
#else
void func()
{
printf(&#34;Release2版本发布\n&#34;);
}
#endif
#endif4 一些特殊的预定宏
// __FILE__ 宏所在文件的源文件名
// __LINE__ 宏所在行的行号
// __DATE__ 代码编译的日期
// __TIME__ 代码编译的时间
//特殊宏
void doWork(char* p)
{
if (p == NULL)
{
printf(&#34;文件: %s 第 %d 行 出错了\n&#34;, __FILE__, __LINE__);
printf(&#34;日期:%s\n&#34;, __DATE__);
printf(&#34;时间:%s\n&#34;, __TIME__);
return;
}
}
void test02()
{
doWork(NULL);
} |
|