10

我正在尝试实现一个灵活的调试宏/函数库,命名/可选参数似乎是实现这些函数的最佳方式。

有没有更好的方法在 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;
    ...
    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(...
        ...
        }
        ...
    }
    ...
}
4

3 回答 3

29

当然。

struct toto {
  unsigned age;
  char name[25];
};

void func(struct toto);

...

func((struct toto){ .name = "you", .age = 18 });

或者,如果您愿意,可以将其包装在宏中

#define FUNC(...) func((struct toto){ __VA_ARGS__ })
...
FUNC(.name = "you", .age = 18 );
于 2011-05-10T09:08:39.407 回答
1

除非命名参数都兼容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);

    /* ... */
}

你会像这样使用它:

named_arg_initializers(&p, AGE, 110, NAME, "Claude Choules", NA_SENTINEL);
于 2011-05-10T13:04:24.573 回答
0

https://github.com/cindRoberta/C/blob/master/structure/function/named_pa​​rameter.c

#include<stdio.h>

typedef struct {
  int a;
  float b;
} named_param;

void f_impl(named_param np) {
  printf("%d %g", np.a, np.b);
}

#define f_macro(...) f_impl((named_param){__VA_ARGS__})

int main() {
  f_macro(.a = 4, .b = 9.7);
  //f_impl((named_param){.a = 7, .b = 6.2});

  return 0;
}
于 2021-11-22T13:44:11.653 回答