我有这样的数据结构:
struct foo {
int id;
int route;
int backup_route;
int current_route;
}
以及一个名为update()的函数,用于请求对其进行更改.
update(42, dont_care, dont_care, new_route);
这真的很长,如果我在结构中添加一些内容,我必须在每次调用更新(...)时添加'dont_care'.
我正在考虑将结构传递给它,但事先用'dont_care'填充结构比在函数调用中拼写它更加繁琐.我可以使用默认值dont care在某处创建结构,并在我将其声明为局部变量后设置我关心的字段吗?
struct foo bar = { .id = 42, .current_route = new_route };
update(&bar);
将我希望表达的信息传递给更新功能的最优雅的方法是什么?
我希望其他一切都默认为-1("不关心"的密码)
hlo*_*dal 153
虽然宏和/或函数(如已经建议的)将起作用(并且可能具有其他积极效果(即调试挂钩)),但它们比需要的更复杂.最简单且可能最优雅的解决方案是仅定义用于变量初始化的常量:
const struct foo FOO_DONT_CARE = { // or maybe FOO_DEFAULT or something
dont_care, dont_care, dont_care, dont_care
};
...
struct foo bar = FOO_DONT_CARE;
bar.id = 42;
bar.current_route = new_route;
update(&bar);
Run Code Online (Sandbox Code Playgroud)
这段代码几乎没有理解间接的精神开销,而且很明显bar你在(安全地)忽略那些未设置的字段时明确设置了哪些字段.
jpa*_*cek 15
您可以将您的秘密特殊值更改为0,并利用C的默认结构成员语义
struct foo bar = { .id = 42, .current_route = new_route };
update(&bar);
Run Code Online (Sandbox Code Playgroud)
然后将作为初始化程序中未指定的bar成员传递0.
或者您可以创建一个将为您执行默认初始化的宏:
#define FOO_INIT(...) { .id = -1, .current_route = -1, .quux = -1, ## __VA_ARGS__ }
struct foo bar = FOO_INIT( .id = 42, .current_route = new_route );
update(&bar);
Run Code Online (Sandbox Code Playgroud)
<stdarg.h>允许您定义可变参数函数(接受无限数量的参数,例如printf()).我将定义一个函数,它接受任意数量的参数对,一个指定要更新的属性,另一个指定值.使用enum或字符串指定属性的名称.
小智 5
也许考虑使用预处理器宏定义:
#define UPDATE_ID(instance, id) ({ (instance)->id= (id); })
#define UPDATE_ROUTE(instance, route) ({ (instance)->route = (route); })
#define UPDATE_BACKUP_ROUTE(instance, route) ({ (instance)->backup_route = (route); })
#define UPDATE_CURRENT_ROUTE(instance, route) ({ (instance)->current_route = (route); })
Run Code Online (Sandbox Code Playgroud)
如果你的(struct foo)实例是全局的,那么你当然不需要参数.但我假设你可能有不止一个实例.使用({...})块是适用于GCC的GNU-ism; 这是一种将线条保持在一起的好方法(安全).如果以后需要向宏中添加更多内容,例如范围验证检查,则不必担心会破坏if/else语句等等.
根据您指出的要求,我会这样做.像这样的情况是我开始大量使用python的原因之一; 处理默认参数等变得比以往任何时候都简单得多.(我猜这是一个python插件,对不起;-)