宏
解决宏与函数重名
函数在前宏在后的重名能正常工作. 宏在前函数在后就需要给函数名加一个括号
调用函数时,不管谁在前都需要给函数名加括号
理解: gcc编译时会把宏展开, 也就是把调用宏的地方全部替换成宏后面的字符串,加上括号后就能起到分隔的作用(即防止被替换),
比如下面的例子,宏在前,gcc编译前会寻找所有f(),然后把f()替换成printf("..."), 而f()函数因为给函数名加了个括号不匹配f(),所以函数定义成功没有被宏替换,在main函数中调用f()函数也需要加括号防止被宏替换
#include <stdio.h>
#define f() printf("macro\n");
void (f)(){printf("function\n");} //f如果不回括号会报错
int main(int argc, const char *argv[]){
f();
(f)();
return 0;
}
宏函数的参数
涉及优先级的宏函数需要给参数加括号
#include <stdio.h>
#define multiply(x,y) x*y
#define multiply2(x,y) (x)*(y)
int main(int argc, const char *argv[]){
printf("%d\n",multiply(2+1,2)); //2+1*2
printf("%d\n",multiply2(2+1,2)); //(2+1)*2
return 0;
}
字符化与连接符
两个井号的连接符与字符串中的strcat不一样,连接符只是一个宏,用于编译前的替换操作,所以想要把两个字符连接起来需要用strcat而不能用连接符,连接符连接后的对象要么是数值要么是已定义的变量名称才有意义
#include <stdio.h>
#define STR(X) #X
#define CONC(X,Y) X##Y
int main(int argc,char *argv[]){
printf("#10=%s\n",STR(10));
printf("10##11=%d\n",CONC(10,11));
char *p1="this is a test string";
printf("%s\n",CONC(p,1));
return 0;
}