#include <stdio.h> #define DEFARG(name, defval) ((#name[0]) ? (name + 0) : defval) int _f1(int i) { return 2*i; } #define f1(arg0) _f1(DEFARG(arg0, 0)) int _f2(int i, int j) { return i + j; } #define f2(arg0, arg1) _f2(DEFARG(arg0, 0), DEFARG(arg1, 1)) int main() { printf("%d\n", f1()); printf("%d\n", f1(1)); printf("%d\n", f2(,)); printf("%d\n", f2(2,)); printf("%d\n", f2(, 3)); printf("%d\n", f2(4, 5)); return 0; }
#define DEFARG(name, defval) ((#name[0]) ? (name + 0) : defval)
#define f1(arg0) _f1(DEFARG(arg0, 0))
#define f2(arg0, arg1) _f2(DEFARG(arg0, 0), DEFARG(arg1, 1))
这几个宏看不懂,是什么意思啊,能提供相关资料了解吗?
解决方案
5
其实这个宏定义是带参数的宏定义:
#define DEFARG(name, defval) ((#name[0]) ? (name + 0) : defval) /*这里,DEFARG是宏名,(name,defval)是他的两个参数名。后面的括号内容是参数的定义方式。这里可以把这个宏看作一个函数,不过他是与处理的: 当#name[0]为真时(无参数),返回name+0; 当#name[0]为假时(有参数),返回defval(默认值) */
例如:
#define f1(arg0) _f1(DEFARG(arg0, 0)) /*对于f1()的调用,原因是#name[0]为真(没有传递参数),所以返回name+0=0; 对于f1(1)的调用,原因是#name[0]为假(有参数传递),所以返回defval=1; */
又例如:
#define f2(arg0, arg1) _f2(DEFARG(arg0, 0), DEFARG(arg1, 1)) /*对于f2(,)的调用,原因是#name[0]为真(没有传递arg0参数),所以返回arg0+0=0; 原因是#name[1]为假(有传递arg1参数),所以返回arg1=1; 所以输出为1; 对于f2(2,0)的调用,参考上面分析:结果为2+1=3; */
15
name + 0 假如 name 为空 变成 +0 正0 也就是 0
假如没有+0 假如为空 就成 “”[0]?:defval
?表达式,缺少了一个表达式,当然就错了
这是一种技巧
#name[0]的意思是将name转换为字符串,然后再取出它的第一个元素?对的
注意空字符串,也有一个元素”\0″
字符串化运算符 #
用于宏定义语句,它的作用如下:
#abc –>”abc”
#1–>”1″
#x–>”x”
字符串 可以当作数组用
“abc”[0] –>‘a’
“abc”[1] –>‘b’
“abc”[2]–>”c”
“abc”[3]–>”\0”
一个只有三个字符,两边加上引号的字符串(其中不包含转义字符,转义字符另有计算法),
一共有四个字符,最后一个是字符串结束符 ‘\0’ ,也就是值为0的字符
假如没有+0 假如为空 就成 “”[0]?:defval
?表达式,缺少了一个表达式,当然就错了
这是一种技巧
#name[0]的意思是将name转换为字符串,然后再取出它的第一个元素?对的
注意空字符串,也有一个元素”\0″
字符串化运算符 #
用于宏定义语句,它的作用如下:
#abc –>”abc”
#1–>”1″
#x–>”x”
字符串 可以当作数组用
“abc”[0] –>‘a’
“abc”[1] –>‘b’
“abc”[2]–>”c”
“abc”[3]–>”\0”
一个只有三个字符,两边加上引号的字符串(其中不包含转义字符,转义字符另有计算法),
一共有四个字符,最后一个是字符串结束符 ‘\0’ ,也就是值为0的字符