1.__FILE__ // 进⾏编译的源⽂件2.__LINE__ // ⽂件当前的⾏号3.__DATE__ // ⽂件被编译的⽇期4.__TIME__ // ⽂件被编译的时间5.__STDC__ // 如果编译器遵循 ANSI C ,其值为 1 ,否则未定义 ,ps:vs不支持
举个例⼦:1-4
5的举例:
预处理替换 :
基本语法:
1 # define name stuff
举个例⼦:
#define MAX 1000
#define reg register //为 register这个关键字,创建⼀个简短的名字
#define do_forever for(;;) //⽤更形象的符号来替换⼀种实现
#define CASE break;case //在写case语句的时候⾃动把 break写上。
// 如果定义的 stuff过⻓,可以分成⼏⾏写,除了最后⼀⾏外,每⾏的后⾯都加⼀个反斜杠(续⾏符)。
#define DEBUG_PRINT printf("file:%s\tline:%d\t \
date:%s\ttime:%s\n" ,\
__FILE__,__LINE__ , \
__DATE__,__TIME__ )
这里就会报错
这里有一个魔鬼细节
可以发现这里是把m直接一模一样的替换的上面而不是先替换,所以如果用define定义的常量参加表达式的计算需要注意计算顺序
举个例子:
#define不仅可以定义数值还可以定义字符串:
1 #define name( parament-list ) stuff
参数列表的左括号必须与name紧邻,如果两者之间有任何空⽩存在,参数列表就会被解释为stuff的 ⼀部分。
1 # define SQUARE( x ) x * x
int a = 5;
printf("%d\n" ,SQUARE( a + 1) );
printf ("%d\n",a + 1 * a + 1 );
只会一模一样的替换上去不会帮我们进行计算所以这里需要自己加上括号
# define SQUARE(x) (x) * (x)
这样预处理之后就产⽣了预期的效果:
printf ( "%d\n" ,(a + 1 ) * (a + 1 ) );
这⾥还有⼀个宏定义:
# define DOUBLE(x) (x) + (x)
定义中我们使⽤了括号,想避免之前的问题,但是这个宏可能会出现新的错误。
int a = 5 ;printf ( "%d\n" , 10 * DOUBLE(a));
printf ("%d\n",10 * (5) + (5));
1 #define DOUBLE( x) ( ( x ) + ( x ) )
所以⽤于对数值表达式进⾏求值的宏定义都应该⽤这种⽅式加上括号,避免在使⽤宏时由于参数中的操作符或邻近操作符之间不可预料的相互作⽤。
1.宏的参数中如果有操作符,和宏的内容中的操作符因为运算符有优先级的问题,可能导致运算顺序不达预期所以容易产生问题
2.宏在书写的时候,给参数都带上括号,不要吝啬括号
上面代码都是让b=a+1,但是第二个的写法直接让a原来的值发生的改变
#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
...
x = 5;
y = 8;
z = MAX(x++, y++);
printf("x=%d y=%d z=%d\n", x, y, z);//输出的结果是什么?
这⾥我们得知道预处理器处理之后的结果是什么:
z = ( (x++) > (y++) ? (x++) : (y++));
所以输出的结果是:x=6 y=10 z=9
在使用宏的时候应该避免使用这种带有副作用的宏
#define MAX(a, b) ((a)>(b)?(a):(b))
#define MALLOC(num, type)\
(type )malloc(num sizeof(type))
...
//使⽤
MALLOC(10, int);//类型作为参数
//预处理器替换之后:
(int )malloc(10 sizeof(int));
宏和函数的⼀个对⽐
#define PRINT(n) printf("the value of "#n " is %d", n);
printf ( "the value of ""a" " is %d" , a);
运⾏代码就能在屏幕上打印:
the value of a is 10
int int_max(int x, int y)
{
return x>y?x:y;
}
float float_max(float x, float y)
{
return x>yx:y;
}
//宏定义
#define GENERIC_MAX(type) \
type type##_max(type x, type y)\
{ \
return (x>y?x:y); \
}
使⽤宏,定义不同函数
GENERIC_MAX(int) //替换到宏体内后int##_max ⽣成了新的符号 int_max做函数名
GENERIC_MAX(float) //替换到宏体内后float##_max ⽣成了新的符号 float_max做函数名
int main()
{
//调⽤函数
int m = int_max(2, 3);
printf("%d\n", m);
float fm = float_max(3.5f, 4.5f);
printf("%f\n", fm);
return 0;
}
输出:
34.500000
在实际开发过程中##使⽤的很少,很难取出⾮常贴切的例⼦。