·#define 是预处理器处理的单元实体之一(是要被预处理器处理的)
·#define 定义的宏可以出现在程序的任意位置
·#define 定义的宏常量可以直接使用
·#define 定义的宏常量本质为字面量
define 的宏定义是字面量,不会占用内存空间的,而 const 是占用内存空间的。
例子 21-1:
include “stdio.h”
define ERROR -1
define PATH1“D:testtest.c”
define PATH1 D:testtest.c
define PATH1 D:test\
test.c”
int main()
{
return 0;
}
输出结果:
define PATH1 D:testtest.c
define PATH1 D:test\
错误,非字面量
define 表达式的使用类似函数调用
define 表达式可以比函数更加强大
define 表达式比函数更容易出错
例子 21-2:
include “stdio.h”
define _SUM_(a , b) (a)+(b)
define _MIN_(a , b) ((a)<(b)?(a):(b))
define _DIM_(a) sizeof(a)/sizeof(*a)
int main()
{
int a = 1;
int b = 2;
int c[4] = {0};
int s1 = _SUM_(a , b);
int s2 = _SUM_(a , b) * _SUM_(a , b);
int m = _MIN_(a++ , b);
int d = _DIM_(c);
printf("s1 = %d\n",s1);
printf("s2 = %d\n",s2);
printf("m = %d\n",m);
printf("d = %d\n",d);
return 0;
}
输出结果:
s1 = 3
s2 = 5
m = 2
d = 4
s2 = a+b*a+b;
m = ((a++)<(b)?(a++):(b)); 其实 a ++ 了两次
·宏表达式被预处理器处理,编译器不知道宏表达式的存在
·宏表达式用“实参”完全代替形参,不进行任何运算
·宏表达式没有任何的“调用”开销
·宏表达式中不能出现递归定义
·宏定义的常量或表达式没有作用域限制
例子 21-3:
include “stdio.h”
void def()
{
define PI 3.141592653
define AREA(r) rrPI
}
double area(double r)
{
return AREA(r);
}
int main()
{
double r = area(5);
printf("a = %f\n",r);
return 0;
}
输出结果:
a = 78.539816
所以说宏定义没有作用域的限制
例子 21-4:
include “stdio.h”
include “malloc.h”
define MALLOC(type, x) (type)malloc(sizeof(type)x)
define FREE(p) (free(p),p = NULL)
define LOG(s) printf(“[%s]{%s:%d} %sn”,_DATA_,_FILE_,_LINE_,s);
define FORACH(i ,m) for(i = 0,i<m,i++)
define BEGIN {
define END }
int main()
{
int x = 0;
int *p = MALLOC(int,5);
LOG("Begin to run main code...");
FORACH(x,5)
BEGIN
p[x] = x;
END
FORACH(x,5)
BEGIN
printf("%d\n",p[x]);
END
FREE(p);
LOG("End");
return 0;
}
宏的强大作用
小结:
·预处理器直接对宏进行文本替换
·宏使用时的参数不会进行求值和运算
·预处理器不会对宏定义进行语法检查
·宏定义时出现的语法错误只能被编译器检测
·宏定义的效率高于函数调用
·宏的使用会带来副作用
狄泰软件学院课堂笔记