【Just For Fun】
本系列纯粹娱乐、研究用。一些旁门左道的东西。
事实上可能完全没用。 (๑•̀ω•́๑)
▌前置知识:
【Just For Fun】C - 可变参数函数、可变参数宏 __VA_ARGS__、额外的逗号
【Just For Fun】C - 宏开发 - 选取第 n 项参数、按照参数数目展开不同的宏、缺陷
【Just For Fun】C - 宏开发 - 真正按照参数数目展开不同的宏、延迟展开
▌默认参数:
在 C++ 下,我们遇到这个情况时:
int sum2(int a, int b){
return a + b;
}
int sum3(int a, int b, int c){
return a + b + c;
}
int sum4(int a, int b, int c, int d){
return a + b + c + d;
}
会使用默认参数进行简化:
int sum(int a, int b = 0, int c = 0, int d = 0){
return a + b + c + d;
}
效果等价上面那三个函数。
然而, C 是没有默认参数的,
下面将会用各种方法实现默认参数。
▌实现默认参数:
上一篇文章提到一个可以按照参数数目展开不同的宏的宏:
#define get5th(a1, a2, a3, a4, a5, ...) a5
#define leftBracket (
#define eatComma(...) ,##__VA_ARGS__
#define select0_3(m0, m1, m2, m3, ...) get5th leftBracket eatComma(__VA_ARGS__), m3, m2, m1, m0)
还有一个应用例子 foo()
:
#define foo(...) select0_3(foo0, foo1, foo2, foo3, __VA_ARGS__)
当参数数目为0
时展开foo0
,
当参数数目为1
时展开foo1
,
当参数数目为2
时展开foo2
,如此类推到3
。
基于这个宏,我们可以轻而易举地实现默认参数。
就以上面的 sum()
作为例子,先实现一个 sum4()
:
int sum4(int a, int b, int c, int d){
return a + b + c + d;
}
然後,
#define sum(a, ...) select0_3(sum4(a, 0, 0, 0),
sum4(a, __VA_ARGS__, 0, 0),
sum4(a, __VA_ARGS__, 0),
sum4(a, __VA_ARGS__),
__VA_ARGS__)
效果等价 sum(int a, int b = 0, int c = 0, int d = 0)
。
就算宏的本身有多难看,
展开到最后还是会很优雅的。
可以进行针对性优化,(人肉展开
还有其他形式可以实现,(把 __VA_ARGS__
放在其他位置
不过用封装好的方法还是比较方便,
并且我很懒 ρ(・ω・、)。w ,就算了,也没什么意义,
——毕竟读者自证不难,留作习题答案略。
▌有趣的发现:
找了一下其他人用宏实现默认参数的方式,
发现一个很特别的方法,
C语言中的参数默认值 - broook的专栏 - CSDN博客
他用了这个东西:
#define DEFARG(name, defval) ((#name[0]) ? (name + 0) : defval)
用 (#name[0]) ? (name + 0) : defval
去进行判断,
很特别,不过占用了运行期的时间,是个很有趣的方法。
___
谢谢阅读本文章!~
___
【Just For Fun】俺 是 目 录 !