预定义符号
C语⾔设置了⼀些预定义符号,可以直接使⽤,预定义符号也是在预处理期间处理的
__FILE__ //进⾏编译的源⽂件
__LINE__ //⽂件当前的⾏号
__DATE__ //⽂件被编译的⽇期
__TIME__ //⽂件被编译的时间
__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义
#define 定义常量
基本语法:
1 #define name stuff
#define MAX 1000
#define reg register //为 register这个关键字,创建⼀个简短的名字
#define do_forever for(;;) //⽤更形象的符号来替换⼀种实现
#define CASE break;case //在写case语句的时候⾃动把 break写上。
在define定义标识符的时候,要不要在最后加 :
#define MAX 1000;
#define MAX 1000
建议不要加上 ; 容易导致问题。
宏的命名规则
⼀般来讲函数的宏的使⽤语法很相似。所以语⾔本⾝没法区分⼆者。
平时的⼀个习惯是:
把宏名全部⼤写
函数名不要全部⼤写
#define定义宏
#define 机制包括了⼀个规定,允许把参数替换到⽂本中,这种实现通常称为宏(macro)或定义宏 (define macro)。
#define name( parament-list ) stuff
其中的
parament-list
是⼀个由逗号隔开的符号表,它们可能出现在stuff中。
注意:
参数列表的左括号必须与name紧邻,如果两者之间有任何空⽩存在,参数列表就会被解释为stuff的 ⼀部分
例子1
例子2
注意:⽤于对数值表达式进⾏求值的宏定义都应该⽤这种⽅式加上括号,避免在使⽤宏时由于参数中的 操作符或邻近操作符之间不可预料的相互作⽤
带有副作⽤的宏参数
当宏参数在宏的定义中出现超过⼀次的时候,如果参数带有副作⽤,那么你在使⽤这个宏的时候就可 能出现危险,导致不可预测的后果。副作⽤就是表达式求值的时候出现的永久性效果
x+1;//不带副作⽤
x++;//带有副作⽤
例子
计算此代码
为什么是这个结果
宏替换的规则
解除宏#undef
#
undef
NAME
宏函数的对⽐
宏通常被应⽤于执⾏简单的运算。
⽐如在两个数中找出较⼤的⼀个时,写成下⾯的宏,更有优势⼀些。
#
define
MAX(a, b) ((a)>(b)?(a):(b))
优势 原因有⼆:
1.
⽤于调⽤函数和从函数返回的代码可能⽐实际执⾏这个⼩型计算⼯作所需要的时间更多。所以宏⽐ 函数在程序的
规模和速度⽅⾯更胜⼀筹。
2.
更为重要的是函数的参数必须声明为特定的类型。所以函数只能在类型合适的表达式上使⽤。反之 这个宏怎可以适⽤于整形、⻓整型、浮点型等可以⽤于 >
来⽐较的类型。
宏的参数是类型⽆关 的。
和函数相⽐宏的劣势:
1.
每次使⽤宏的时候,⼀份宏定义的代码将插⼊到程序中。除⾮宏⽐较短,否则可能⼤幅度增加程序的⻓度。
2.
宏是没法调试的。
3.
宏由于类型⽆关,也就不够严谨。
4.
宏可能会带来运算符优先级的问题,导致程容易出现错
宏有时候可以做函数做不到的事情。⽐如:宏的参数可以出现类型,但是函数做不到
#define MALLOC(num, type) (type )malloc(num sizeof(type))
...
//使⽤
int*p= MALLOC(10, int);//类型作为参数
//预处理器替换之后:
(int *)malloc(10 sizeof(int));