C 支持可选的空参数吗?

问题描述 投票:0回答:6

在 Python 中,我习惯了这样的事情

def send_command(command, modifier = None):

然后修饰符参数是可选的,没有该参数可以与参数为 0 区分开来。C 中有类似的功能吗? 我对 C 和 Google 没有经验,但找不到如何在 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 null optional-parameters function-declaration function-parameter
6个回答
19
投票

C 不支持可选参数。它也不支持函数重载,而函数重载通常可以达到类似的效果。


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))
,等等


3
投票

正如其他人所说,C 没有可选参数。

至于

NULL
0
之间的区别,没有太大的区别


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++相同,即默认参数的求值上下文是声明的上下文。还可以通过求值上下文是宏调用上下文的方式来指定这一点。


0
投票

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


0
投票

使用结构体

通过使用结构体,C 中可以有可选参数,甚至是带标签的参数:

typedef struct {
    int a, b, c;
} Options;

void func(Options options);

然后,像这样调用

func
(自 C99 起):

func((Options){ 1, 2 });
func((Options){ .c = 3 });

未指定的值默认为零。

如果你可以使用宏,你可以写:

#define func(...) func((Options){ __VA_ARGS__ })

这样你就可以这样打电话:

func(1, 2);
func(.c = 3);

您甚至可以指定零以外的值(这与 C++ 不兼容):

struct options {
    char unused;
    int a, b, c;
};

void func(struct options options);
#define func(...) func((struct options){ .a = 1, 2, 3, .unused = 0, __VA_ARGS__ })

好吧,这变得相当难看。

还要记住,传递结构体作为参数会使程序变慢(因为结构体存储在内存中,而简单值(例如整数和指针)存储在寄存器中),因此这些结构体解决方案当然不应该用于低级函数需要性能。

我经常使用结构体来提供可选的、默认为空的参数。我尝试使用我的宏想法,但它似乎从来都不是一个好主意。

我不明白为什么其他人没有像我一样花这么多时间思考结构......!

使用数组技巧

让我们继续讨论丑陋的代码。有时我使用这个技巧(从 C99 开始也有效):

void func(int a, int b, int c);
#define func(a, ...) func(a, (int[2]){ __VA_ARGS__ }[0], (int[2]){ __VA_ARGS__ }[1])

然后您可以使用 1、2 或 3 个参数调用

func
,如果未指定,
b
c
默认为零。

请注意,编译器优化将消除数组。

© www.soinside.com 2019 - 2024. All rights reserved.