C语言是否支持可选的空参数?

8
在Python中,我习惯于像这样的事情

def send_command(command, modifier = None):

然后修饰符参数是可选的,缺少该参数可以与参数为0区分开来。在C语言中是否有类似的功能?我对C语言不熟悉,并进行了谷歌搜索,但找不到如何在C语言中使用可选参数的明确说明。看起来你可以通过类似的方式赋值:

void send_command(uint8_t command, uint8_t modifier = 0) {

所以第二个参数是可选的,如果不使用默认为0?(编辑:不,这是无效的C语言)

但是这个函数能区分send_command(SOMETHING)send_command(SOMETHING, 0)吗?理想情况下,第二个参数可以是任何uint8值,包括0。

也许NULL与0不同?

void send_command(uint8_t command, uint8_t modifier = NULL) {

请参阅:C语言中的函数重载 - Sjoerd
5个回答

19

C语言不支持可选参数。它也不支持函数重载,虽然函数重载常常可以实现类似效果。


这可能是我找不到它的原因。所以,我的示例分配默认值0只在C++中有效吗? - endolith
3
没问题。在C++中,这被称为默认参数(default argument)。 - David Heffernan

14

在C99中,使用可变宏可以实现可选参数:

#define JUST3(a, b, c, ...) (a), (b), (c)
#define FUNC(...) func(JUST3(__VA_ARGS__, 0, 0))

现在FUNC(x)会被扩展为func((x), (0), (0))FUNC(x,y)会被扩展为func((x), (y), (0)),以此类推。


13
我不知道是该哭还是笑。 - pmg
你不想看到重载,是吧?;-) - R.. GitHub STOP HELPING ICE
2
不幸的是,FUNC(x,y,z,t)会扩展为func((x),(y),(z))而不是出现错误。我认为重要的事情就是稍微惩罚那些希望进行过载的人。在他们最不期望的时候。 - Steve Jessop
1
完全合理。我认为最好的答案是“不,C没有它们[除非你喜欢邪恶的预处理器黑客]”。 - R.. GitHub STOP HELPING ICE
1
尽管如此,模仿 void send_command(int command = 1; int modifier = 0) 是有一定难度的,因为无论您在 __VA_ARGS__ 后面添加什么值,它都将被用作任一参数的默认值。这是“默认参数”或“重载”的较差版本。显然 R.. 知道这一点,这主要是出于兴趣而呈现的。警告不要真的使用这个应该被遵守! - Steve Jessop
显示剩余4条评论

3

1
那要看情况。将NULL定义为(void *)0,在大多数编译器中,当传入整数参数时会导致“从指针到整数的转换没有强制转换”的警告。我觉得C++委员会选择使用纯0相当奇怪,这甚至破坏了保留C定义所需的最基本类型检查。 - Tom Lint

2

如其他人所说,C语言不直接支持函数的默认参数。但是可以通过宏来实现。 P99提供了方便的“元”宏,使得指定该特性相对容易。例如,为了避免反复指定pthread_mutex_init函数的第二个参数:

P99_PROTOTYPE(int, pthread_mutex_init, pthread_mutex_t*, pthread_mutexattr_t const*);
#define pthread_mutex_init(...) P99_CALL_DEFARG(pthread_mutex_init, 2, __VA_ARGS__)
P99_DECLARE_DEFARG(pthread_mutex_init, , (pthread_mutexattr_t*)0);

并且易于使用。
pthread_mutex_init(&my_mutex);

在这里,对于默认参数的评估语义与C++相同,即默认参数的评估上下文是声明的上下文。还可以通过指定宏调用上下文来评估默认参数的上下文。请注意保留HTML标签。

0

C语言没有可选参数。C++有,但是“许多现代编程语言之母”C语言没有...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接