#define机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏或定义宏。
宏的申明方式:
#define name(parament-list) stuff
其中parament-list是一个由逗号隔开的符号表,它们可能出现在stuff中
注意:
参数列表的左括号必须与name紧邻,如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分
1.宏的参数不是传参 而是替换
实例1:
#define SQUARE(X) X*X
int main()
{
//int ret = SQUARE(5);
5*5
//printf("%d\n", ret);//25
int ret = SQUARE(5 + 1);
//#define SQUARE(X) X*X
//5+1 5+1*5+1=11
printf("%d\n", ret);//11
return 0;
}
#define SQUARE(X) (X)*(X)
int main()
{
int ret = SQUARE(5 + 1);
//(5+1)*(5+1)
printf("%d\n", ret);//36
ret
实例2:
#define DOUBLE(X) (X)+(X)
int main()
{
int a = 5;
int ret = 10 * DOUBLE(a);
//10*(a)+(a)
printf("%d\n", ret);//55
return 0;
}
#define DOUBLE(X) ((X)+(X))
int main()
{
int a = 5;
int ret = 10 * DOUBLE(a);
//10*((a)+(a))
printf("%d\n", ret);//100
return 0;
}
所以用于对数值表达式进行求值的宏定义都应该用这种方式加上括号,
避免在使用宏时由于参数中的操作符或邻近操作符之间不可预料的相互作用
2.#可以把一个宏参数变成对应的字符串
#define PRINT(X) printf("the value of"#X"is %d\n",X)
int main()
{
printf("hello world\n");//hello world
printf("hello"" world\n");//hello wold
//字符串有自动连接的特点
int a = 10;
int b = 20;
PRINT(a);
//printf("the value of""a""is %d\n",a);
PRINT(b);
return 0;
}
3.##可以把位于它两边的符号合成一个符号,它允许宏定义从分离的文本片段创建标识符
#define CAT(X,Y) X##Y
int main()
{
int CLASS84 = 2019;
printf("%d\n", CLASS84);//2019
printf("%d\n", CAT(CLASS, 84));//2019
return 0;
}
4.带副作用的宏参数
#define MAX(X,Y) (X)>(Y)?(X):(Y)
int main()
{
int a = 10;
int b = 11;
//int max = MAX(a,b);
//printf("%d\n", max);//11
int max = MAX(a++, b++);
//(a++)>(b++)?(11):(b++)
printf("%d\n", max);//12
printf("%d\n", a);//11
printf("%d\n", b);//13
return 0;
}
5.#undef:用于移除一个宏定义
#undef NAME
如果现存的一个名字需要被重新定义 那么它的旧名字首先要被移除