CONTENTS
宏返回值
以下内容转自【 http://blog.csdn.net/fjb2080/article/details/5174171 】,有删改。
在使用逗号表达式中有一点需要注意的是,在逗号表达式中不可以声明变量。
例如:
int n = (int a=5, ++a); //这是错误的
可以这样使用:
int a; int n = (a=5, ++a);
那么n的值就是6;
另外在gcc中亦可用{}表达式作为返回值,如:
#define fucn1(a) ({a= a+5; a;})
例如下面一个例子:
#include <stdio.h> #define func(a) ({a=a+5; a;}) int main(void) { //int i; //int a = (i=5, ++i); int a=0; int b = func(a); printf("a=%d/n", a); printf("b=%d/n", b); return 0; }
输出:
a=5 b=5
GCC对于宏返回值的描述:【 http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html 】
可变参数宏
以下内容转自【www.cnblogs.com/caosiyang/archive/2012/08/21/2648870.html 】,有删改。
C99中规定宏可以像函数一样带有可变参数,比如
#define LOG(format, ...) fprintf(stdout, format, __VA_ARGS__)
其中,…表示参数可变,__VA_ARGS__在预处理中为实际的参数集所替换
GCC中同时支持如下的形式
#define LOG(format, args...) fprintf(stdout, format, args)
其用法和上面的基本一致,只是参数符号有变化
有一点需要注意,上述的宏定义不能省略可变参数,尽管你可以传递一个空参数,这里有必要提到”##”连接符号的用法。
“##”的作用是对token进行连接,在上例中,format、__VA_ARGS__、args即是token,如果token为空,那么不进行连接,所以允许省略可变参数(__VA_ARGS__和args),对上述变参宏做如下修改
#define LOG(format, ...) fprintf(stdout, format, ##__VA_ARGS__) #define LOG(format, args...) fprintf(stdout, format, ##args)
自己写的小测试:
#include <stdio.h> int calcnum(int a, int b) { a = a+ b + 10; b = b+5; return b; } #define CALCNUM(a,b) \ ({\ a = a+ b + 10;\ b = b+5;\ b;\ }) #define LOGA(format, ...) printf(format,__VA_ARGS__) #define LOGB(format, ...) printf(format,##__VA_ARGS__) #define LOGC(format, xx...) printf(format,##xx) /*重命名可变参数*/ int main(void) { int a = 3, b = 5; int result = calcnum(a,b); printf("result:%d a:%d b:%d\n", result,a,b); a = 3, b = 5; result = CALCNUM(a,b); printf("result:%d a:%d b:%d\n", result,a,b);/* 注意这里的ab和上面的值是不同的。 */ /*无可变参数,无法编译通过。*/ // LOGA("Hello World A\n"); LOGB("Hello World B\n"); LOGC("Hello World C\n"); LOGA("Hello World A %s\n","OMG"); LOGB("Hello World B %s\n","OMG"); LOGC("Hello World C %s\n","OMG"); return 0; }
输出:
result:10 a:3 b:5 result:10 a:18 b:10 Hello World B Hello World C Hello World A OMG Hello World B OMG Hello World C OMG
发表评论