有没有更好的方法来实现c命名参数?
我正在尝试实现一个灵活的调试宏/函数库,命名/可选参数似乎是实现这些函数的最佳方式 在c语言中,有没有更好的方法来实现命名参数呢有没有更好的方法来实现c命名参数?,c,named-parameters,C,Named Parameters,我正在尝试实现一个灵活的调试宏/函数库,命名/可选参数似乎是实现这些函数的最佳方式 在c语言中,有没有更好的方法来实现命名参数呢 enum named_args {NAME,ADRESS,AGE,NA_SENTINEL}; void named_arg_initializers(struct person p, enum * named_args) { enum named_args * current_name; enum named_args * current_arg;
enum named_args {NAME,ADRESS,AGE,NA_SENTINEL};
void named_arg_initializers(struct person p, enum * named_args)
{
enum named_args * current_name;
enum named_args * current_arg;
...
if(named_args==NULL)
return;
current_name = named_args[0];
current_arg = named_args[1];
while(current_name!=NA_SENTINEL)
{
current_name+=2;
current_arg+=2;
if(current_name==NAME)
p.name=current_arg;
else if(...
...
}
...
}
...
}
当然
或者,如果需要,可以将其包装在宏中
#define FUNC(...) func((struct toto){ __VA_ARGS__ })
...
FUNC(.name = "you", .age = 18 );
除非指定的参数都与
enum
兼容,否则您显示的方式无效(您可以使用void*
参数来修复此问题)
但是,您可以对看起来更整洁的varargs执行类似的操作:
#include <stdarg.h>
enum named_args { NAME, ADDRESS, AGE, NA_SENTINEL };
void named_arg_initializers(struct person *p, ...)
{
va_list ap;
enum named_args argn;
va_start(ap, p);
for (argn = va_arg(ap, enum named_args); argn != NA_SENTINEL; argn = va_arg(ap, enum named_args))
{
switch (argn)
{
case NAME:
p->name = va_arg(ap, char *);
break;
case AGE:
p->age = va_arg(ap, int);
break;
/* ... */
}
}
va_end(ap);
/* ... */
}
老实说,这个问题有点奇怪。。。结尾的“then”一词让它看起来似乎不是一个真正的问题(我不知道它会是什么),而缺少正文和所有内容并不能让它看起来像一个伟大的问题。尝试修正缩进,并在正文中添加一点文字,使其更加生动。(去掉标题中的“then”,因为它有点尴尬。):“nicer”是什么意思?你的标准是什么?您的目标是什么?可以在此处找到一个较老的问题,其答案解决了这一个(及更多)问题:。特别是,请参见u0b34a0f6ae的答案。@Roman,你所说的“仅C99”是什么意思。自12年以来,C99一直是C的标准。是的,C中的所有初始化都将省略的字段放入
0
。只需将其记录为0
有效的字段的默认值:)有些项目不喜欢c99 plus,Microsoft编译器不支持指定的初始值设定项。初始化可能很重要。虽然我听起来有点挑剔,但你的答案很好(我投了更高的票)。尤其是与我的或大多数我认为它是类型安全的方式不同的事实。@Jens:MicrosoftC编译器不兼容C99,而且可能永远也不会兼容。此外,答案似乎是无效的C++,这意味着没有微软开发人员可以使用它,这是所有C和C++程序员的一个重要比例。重点仍然是,这是一个C99唯一的答案,因此指出这一点是合理的,因为使用Microsoft编译器编程C的人不能使用它。谢谢你,这就是我没有编译我的问题的原因,时间太晚了,我正试图找到一种使用类型化参数的方法,不能,忘了让参数无效*。
#include <stdarg.h>
enum named_args { NAME, ADDRESS, AGE, NA_SENTINEL };
void named_arg_initializers(struct person *p, ...)
{
va_list ap;
enum named_args argn;
va_start(ap, p);
for (argn = va_arg(ap, enum named_args); argn != NA_SENTINEL; argn = va_arg(ap, enum named_args))
{
switch (argn)
{
case NAME:
p->name = va_arg(ap, char *);
break;
case AGE:
p->age = va_arg(ap, int);
break;
/* ... */
}
}
va_end(ap);
/* ... */
}
named_arg_initializers(&p, AGE, 110, NAME, "Claude Choules", NA_SENTINEL);