C语言中的参数默认值

liu15073458538 2016-04-29 09:07:30

#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))

这几个宏看不懂,是什么意思啊,能提供相关资料了解吗?
...全文
1892 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2016-04-30
  • 打赏
  • 举报
回复
#name ---->"name" #是字符串化运算符 可以把一个符号,转换为对应的字符串(两端加上引号) #define DEFARG(name, defval) ((#name[0]) ? (name + 0) : defval) 如果 name 不是空格 ,例如 name 是1 那么么 #name[0] 也就是 “1”[0] 是字符‘1’为真 这个问号表达式的值就是 name + 0 也就是 name 本身 ,这里就是1 如果是 x 那么值就是 x 这样不论是变量,还是常量 都得到他本身 如果 name 是空格,则#name 是 "" 空串,“”[0] 就是'\0' 是值为 0 的字符,为假 此时问好表达式的值为 defval 所以这个宏的意思就是 name 为空,取缺省值defval,不为空取 name的值 这对于指针,整型数据,浮点数据等等都有效 #define f1(arg0) _f1(DEFARG(arg0, 0)) 相当于,给无缺省值的函数(C式样的函数),针对某一个参数增加一个缺省值, 相当于 inline int f1 (int a=0){ return _f1(a); } 但是比C++缺省值,更加好用些,可以给任何一个参数加上缺省值。 #define f2(arg0, arg1) _f2(DEFARG(arg0, 0), DEFARG(arg1, 1)) 给 _f2的每个参数,都加个缺省值,分别为0,1 函数调用方式没有参数的地方,就是有缺省值的
lm_whales 2016-04-30
  • 打赏
  • 举报
回复
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的字符
liu15073458538 2016-04-30
  • 打赏
  • 举报
回复
引用 2 楼 lm_whales 的回复:
#name ---->"name" #是字符串化运算符 可以把一个符号,转换为对应的字符串(两端加上引号) #define DEFARG(name, defval) ((#name[0]) ? (name + 0) : defval) 如果 name 不是空格 ,例如 name 是1 那么么 #name[0] 也就是 “1”[0] 是字符‘1’为真 这个问号表达式的值就是 name + 0 也就是 name 本身 ,这里就是1 如果是 x 那么值就是 x 这样不论是变量,还是常量 都得到他本身 如果 name 是空格,则#name 是 "" 空串,“”[0] 就是'\0' 是值为 0 的字符,为假 此时问好表达式的值为 defval 所以这个宏的意思就是 name 为空,取缺省值defval,不为空取 name的值 这对于指针,整型数据,浮点数据等等都有效 #define f1(arg0) _f1(DEFARG(arg0, 0)) 相当于,给无缺省值的函数(C式样的函数),针对某一个参数增加一个缺省值, 相当于 inline int f1 (int a=0){ return _f1(a); } 但是比C++缺省值,更加好用些,可以给任何一个参数加上缺省值。 #define f2(arg0, arg1) _f2(DEFARG(arg0, 0), DEFARG(arg1, 1)) 给 _f2的每个参数,都加个缺省值,分别为0,1 函数调用方式没有参数的地方,就是有缺省值的
为什么要name + 0呢?不加0就出错,还有#name[0]的意思是将name转换为字符串,然后再取出它的第一个元素?这个理解正确吗
iinilostme 2016-04-30
  • 打赏
  • 举报
回复
#,预编译时会作为连接字符,将#name当成字符串
TrevorDeWitt 2016-04-29
  • 打赏
  • 举报
回复
其实这个宏定义是带参数的宏定义:
#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;
*/
下面这篇文章有很详细的介绍,可以了解一下 blog.163.com/xuwenqiang_1989/blog/static/49074935201132433318770/

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧