版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_24890953/article/details/52903801
预处理,在程序编译之前先进行处理,
#define reg register
#define do_forever for( ; ; )//实现无限循环的语句
#define CASE break;case //会在每个case之前放一个break
#define malloc //将语句注释空,可以有效控制程序随意引用
#undef malloc //取消定义恢复原本状态
当定义中的stuff 很长,可以分成几行,除了最后一行之外,其余每一行都要加入一个反斜杠 \ ,如下面的例子
#define DEBUG_PRINT printf( "File %s line %d:" \
"x = %d, y = %d, z = %d", \
__FILE__,__LINE__, \
x ,y ,z )
预定义的符号
符号 | 样例值 | 含义 |
__FILE__ | "name.c" | 进行编译的源文件名 //在确认调试输出的来源很有用处 |
__LINE__ | 25 | 文件当前行的行号 //在确认调试输出的来源很有用处 |
__DATE__ | "Jan 31 1995 " | 文件被编译的日期 |
__TIME__ | "18 : 04:30 " | 文件被编译的时间 |
__STDC__ | 1 | 如果遵循ANSIC,其值就是1,否则为定义 |
在define的语句之后不能加“;” 系统在编译的时候会自动加上去
假设你需要这样的宏定义
#define SQUARE(x) ((X) * (X))
这样就可有效的避免很多问题
使用技巧
#define PRINT( FORMAT , VALUE) \
printf( "The value of "
#VALUE \
" is " FORMAT "\n" ,VALUE)
PRINT( "%d" ,x+3);
the value of x+3 is 25
## 会把两边的符号连成一个符号,前提是产生的符号必须是合法的
#define ADD_TO_SUM( sum_number , value ) \
sum ## sum_number +=25
ADD_TO_SUM(5,25);
结果 sum5 = 25.
宏常用语频繁地执行简单的计算
比如比较大小
#define MAX( a, b ) ((a) > (b) ? (a) : (b) )
#undef
用于移除去一个宏定义,如果现存的名字需要被重新定义,旧定义必须先用#undef移除
条件编译
#if DEBUG
printf(`````);
#endif
DEBUG 为 1,编译内容,为0则删除内容语句
#if
#elif
#else
#endif
#elif 只有前面都是假才能被编译
#else 只有前面都是假才会编译
#if defined( symbol )
#ifdef symbol
#if !defined( symbol )
#ifndef symbol
每队语句之间都是等价的,但是#if的功能更强一点,都是说假如定义了symbol 才会怎么样
#if X>0 || defined( ABC ) &&defined (BCD)
嵌套指令
#if defined(OS_UNIX) //#ifdef 也可以代替
#ifdef OPTION1
unix_version_of_option1();
#endif
#ifdef OPTION2
unix_version_of_option2();
#endif
#elif defined(OS_MSDOS)
#ifdef ----
unix_version_of_option2();
#endif
#endif
相比把程序所需的所有声明放入一个巨大头文件,还不如每个头文件包含用于某个特定函数或模块的声明的做法更好一些
为了避免重复定义统一头文件
#ifndef _HEADERNAME_H
#define _HEADERNAME_H 1 //#define _HEADERNAME_H 也行
#error text of error message
#if defined ()
stuff ```
#elif defined()
stuff ''
#elif defined()
````
#else
#error No`````````````
#endif
用error 产生错误信息
#line number “string”//通知预处理器下一行输入的是行号
#progma 用于支持因编译器而异的特性