C语言宏接收函数及其参数
标签:c/c++
首先看一段代码:
#include <stdio.h>
#include <stdlib.h>
#define call_optimized(function, arguments) {\
printf("\n-------------"); \
printf("\n\tCALL %s\n", #function); \
function arguments; \
printf("-------------\n"); \
}
void foo(char *str) {
printf("%s\n", str);
}
void foo2(char *str1, char *str2) {
printf("%s, %s\n", str1, str2);
}
int main() {
printf("FIRST call_optimized\n");
call_optimized(foo, ("hell world"));
printf("\nSECOND call_optimized");
call_optimized(foo2, ("hell", "world"));
system("pause");
return 0;
}
- 执行结果
宏中有一个地方需要注意,即#符号,在宏中有几个类似的符号,下面进行简要介绍
##
连接符
功能是在带参数的宏定义中将两个子串(token)联接起来,从而形成一个新的子串。或者理解为##是将宏定义的多个形参连接成一个实际的参数名。
如:
(1)示例一
#define exampleNum(n) num##n
int num9=9;
使用:int num=exampleNum(9);
将会扩展成 int num=num9;
(2)示例二#define A1(name, type) type name_##type##_type 或 #define A2(name, type) type name##_##type##_type A1(a1, int); /* 等价于: int name_int_type; */ A2(a1, int); /* 等价于: int a1_int_type; */
其中,A2操作有问题,原因是不恰当的分割导致变量的替换而不是连接操作。
【注意】
1.当用##连接形参时,##前后的空格可有可无。
如:#define exampleNum(n) num ## n
相当于#define exampleNum(n) num##n
2.连接后的实际参数名,必须为实际存在的参数名或是编译器已知的宏定义。#
符号
#连接符是把传递过来的参数当成字符串进行替代。其只能用于有传入参数的宏定义中,且必须置于宏定义体中的参数名前。
如:#define example(instr) printf("the input string is:/t%s/n",#instr) #define example1(instr) #instr
当使用该宏定义时:
example(abc);
在编译时将会展开成:printf("the input string is:/t%s/n","abc");
string str=example1(abc);
将会展成:string str="abc";
注意:
对空格的处理- 忽略传入参数名前面和后面的空格。
如:str=example1( abc );
将会被扩展成str="abc";
- 当传入参数名间存在空格时,编译器将会自动连接各个子字符串,用每个子字符串中只以一个空格连接,忽略其中多余一个的空格。
如:str=exapme( abc def);
将会被扩展成str="abc def";
- 忽略传入参数名前面和后面的空格。
@#
(charizing)字符化操作符。
只能用于有传入参数的宏定义中,且必须置于宏定义体中的参数名前。作用是将传的单字符参数名转换成字符,以一对单引用括起来。#define makechar(x) #@x a = makechar(b);
展开后变成了:
a= 'b';