假设我们有以下参数来描述一个人:name(字符串)和age(无符号整型).我想编写一个通用的setter API函数,人们可以调用该函数来设置特定人员的姓名或年龄.原因将在下面解释.

我所做的是定义Person参数名称的枚举类型:

typedef enum person_param_name
{
    NAME,
    AGE,
} person_param_name_t;

也是Person参数值的联合类型:

typedef union person_param_val
{
    char* name;
    unsigned int age;
} person_param_val_t;

现在,该函数如下所示:

int set_person_param(person_param_name_t param_name, person_param_val_t param_val)
{
    int ret = 0;

    switch (param_name)
    {
        case NAME:
            g_person_name = param_val.name;
            break;
        case AGE:
            g_person_age = param_val.age;
            break;
        default:
            ret = -1;
            break;
    }

    return ret;
}

这种方法的问题是不能像这样简单地调用setter函数(编译器抛出警告):

set_person_param(NAME, "Alex");
set_person_param(AGE, 5);

但它们必须将参数值显式转换为person_param_val_t类型,如下所示:

set_person_param(NAME, (person_param_val_t)"Alex");
set_person_param(AGE, (person_param_val_t )5);

我之所以想要通用的setter函数,是因为在实际的程序中,我有更多的参数(接近100),并且我需要编写许多(非常类似的)setter函数,这将需要更多的代码行.

有没有更好的方法来解决这个问题?

推荐答案

如果更改联合,使字段名与枚举常量相同:

typedef union person_param_val
{
    char* NAME;
    unsigned int AGE;
} person_param_val_t;

然后,您可以创建一个宏来传递正确初始化的复合文字:

#define set_person_param_ext(k,v) \
        set_person_param(k, (person_param_val_t){.k=v})

然后是这个:

set_person_param_ext(NAME, "Alex");
set_person_param_ext(AGE, 5);

将扩展到以下范围:

set_person_param(NAME, (person_param_val_t){.NAME="Alex"});
set_person_param(AGE, (person_param_val_t){.AGE=5});

C++相关问答推荐

exit(EXIT_FAILURE):Tcl C API类似功能

为什么在C中二维字符数组会有这样的行为?

不会停在空格或换行符上的错误

`#if`条件中是否允许`sizeof`?

如何在ASM中访问C struct 成员

GCC不顾-fno-Builtin-SINCOS旗帜向SINCOS发出呼唤

进程在写入管道时挂起

在循环中复制与删除相同条件代码的性能

等同于铁 rust 的纯C语言S未实现!()宏

For循环不会迭代所有字符串字符吗?(初学者问题)

C语言中MPI发送接收字符串时出现的分段错误

pthread_create的用法

哪个首选包含第三个库S头文件?#INCLUDE;文件名或#INCLUDE<;文件名&>?

浮动目标文件,数据段

如何在C中计算包含递增和递减运算符的逻辑表达式?

是否可以在多字 C 类型中的任何位置混合存储和类型限定符?

Makefile - 将 .o 文件放入子文件夹中

C11 嵌套泛型

如何在 C 中的 Postgres 函数的表中 for 循环

C 有没有办法比较多个字符串? [我通过fgets()输入它们]