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

发布于 2025-01-03 07:10:45 字数 606 浏览 0 评论 0原文

在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) {

In Python, I'm used to things like

def send_command(command, modifier = None):

and then the modifier argument is optional, and the absence of the argument can be differentiated from an argument of 0. Is there similar functionality in C? I'm inexperienced with C, and Googling, but can't find a clear statement of how to use optional parameters in C. It seems you can assign them similarly, like this:

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

so the second argument is optional and defaults to 0 if not used? (Edit: No, this is invalid C anyway)

But can the function distinguish between send_command(SOMETHING) and send_command(SOMETHING, 0)? Ideally, the second parameter could be any uint8 value, including 0.

Maybe NULL is different from 0?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

怪我太投入 2025-01-10 07:10:45

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

C does not support optional parameters. Nor does it support function overloading which can often be used to similar effect.

幼儿园老大 2025-01-10 07:10:45

在 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)) 等。

Optional parameters are possible in C99 with variadic macros:

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

Now FUNC(x) expands to func((x), (0), (0)), FUNC(x,y) expands to func((x), (y), (0)), etc.

爺獨霸怡葒院 2025-01-10 07:10:45

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

至于NULL0的区别,没有太多

As others have said, C does not have optional parameters.

As for the difference between NULL and 0, there isn't much of one.

情绪失控 2025-01-10 07:10:45

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

As others said C doesn't support default arguments of functions directly. But there are ways to do this with macros. P99 has convenient "meta"-macros that make this feature relatively easy to specify. As an example to avoid to repeatedly have to specify the second argument of the pthread_mutex_init function:

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

and straight forward to use afterwards

pthread_mutex_init(&my_mutex);

The semantic of evaluation of the default argument here is the same as for C++, that is the evaluation context of the default argument is the context of the declaration. There is also the possibility to specify this in a way that the context of evaluation is the context of the macro invocation.

少女情怀诗 2025-01-10 07:10:45

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

The C Programming Language has no optional parameters. C++ does, but "the mother of many modern programming languages" C does not...

摘星┃星的人 2025-01-10 07:10:45

使用结构体

通过使用结构体,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 个参数、bc 调用 func > 如果未指定,则默认为零。

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

Using a struct

It is possible to have optional arguments in C, and even labeled ones, by using a struct:

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

void func(Options options);

Then, call func like this (since C99):

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

Non-specified values are defaulted to zero.

If you're okay with using a macro, you can write:

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

so that you can call like this:

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

You can even specify values other than zero (this is incompatible with 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__ })

Well, this is becoming quite ugly.

Also remember that passing a struct as argument makes your program slower (because the struct is stored in memory while simple values such as ints and pointers are stored in registers), so these struct-solutions should certainly not be used for low-level functions which need performance.

I very often use structs to have optional, defaultly-nulled arguments. I tried to use my ideas of macros but it never seemed to be a good idea.

I don't understand why others didn't think about structs like me in so much time…!

Using a trick with arrays

Let's go on a bit with ugly code. Sometimes I used this trick (works also since C99):

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

Then you can call func with either 1, 2 or 3 arguments, with b and c defaulting to zero if not specified.

Note that compiler optimizations will get rid of the arrays.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文