源程序经编译器编译一般有如下几个过程
预处理:完成头文件展开,条件编译,会先完成去注释,再进行宏替换。
编译:将C语言翻译成汇编
汇编:将汇编转译成二进制
链接:将二进制文件链接成可执行程序
#define
- 当使用宏来对多条语句进行替换时,可使用
do...while(0)
结构,其后可以添加分号,构成一个完成的域
#include <stdio.h>
#define SetValue(x, y) do{a = 1; b = 2;}while(0)
int main()
{
int a,b;
SetValue(a, b);
printf("a = %d ; b = %d\n", a, b);
return 0;
}
- 宏可以在代码中任何地方定义,但是宏必须定义在调用之前,宏只在定义处往后的文本文件中有效。可以用
#undef
限制宏的作用范围
条件编译
#define Cprogram
//判定宏是否被定义,Cprogram值是1或0不重要
#ifdef Cprogram
#else
#endif
//判定宏是否被定义
#ifndef Cprogram
#else
#endif
//判断宏真假,若if后的宏为假或未定义,条件判断就不成立。但是定义了,必须指定宏的值,否则#if报错
#if Cprogram
#elif
#else
#endif
//#if可对是否定义宏进行判断,为了明确它的这个用法可以如下使用
#if defined(Cprogram) //#if !defined(Cprogram)
#else
#endif
//#if好处是还可以对多个宏进行检测
#if (defined(Cprogram) && defined(Pyprogram))
- gcc编译可使用
-D
选项指定宏定义,不必在程序中定义。
其他预处理指令
- #error :自定义编译报错,其后跟报错信息,可用于检验条件编译
#ifndef
#error 自定义报错信息
#endif
- #line
//预定义符号:__FILE__ :打印文件名
// __LINE__ :打印行号
#line 1 "filename" //分别修改__LINE__和__FILE__的值
- #pragma
#pragma warning(disable:4996) //vs禁止安全报错
#ifdef C
#pragma message("宏C已经被定义")
#endif
单#和双#预算符
- ‘#’
#define TransStr(s) #s //将s的值转化为字符串
printf("Name:"TransStr(ZhangFei)"\n" );
相邻字符串具有自动连接特性,如:
printf("hello""world\n");
- ‘## ’
#define CLOTH(Base, n) Base##e##n //连接字符串,构建科学计数法
int main()
{
printf("%f\n", CLOTH(2, 2));
return 0;
}