如果我有类似的结构
typedef struct {
idx_type type;
union {
char *str;
int num;
} val
} cust_idx;
我有这样的循环
for (i = 0; i < some_get(x); i++) {
some_fun(z, NULL, i);
}
我想重构以使用some_fun(z, idx)
之类的结构,其中idx
是我的cust_idx
结构之一,最好保留i
作为循环计数器并更新idx
或将for标头更改为使用idx.val.num
而不是i
?
为此,假设idx_type
是字符串和数字类型的枚举,并且所有其他字段都将具有宏,但是我仅在此处使用IDX_NUM
宏我不担心与idx.type
有任何关系。
总结我的担忧:
#define IDX_NUM(x) (x.val.num)
...
cust_idx j;
j.type = TYPE_num;
for (IDX_NUM(j) = 0; IDX_NUM(j) < some_get(x); IDX_NUM(j)++) {
some_fun(z, j);
}
这与原始代码的功能相同,但是在我看来,使用struct字段/宏会扩展for循环标头并使之变得复杂,但这仍然是可以理解的。
cust_idx j;
j.type = TYPE_num;
for (i = 0; i < some_get(x); i++) {
IDX_NUM(j) = i;
some_fun(z, j);
}
从逻辑上讲,这导致对旧代码的更改最少,但由于添加了赋值行,因此最后的代码量最大。
cust_idx j;
int *i = &(j.val.num);
j.type = TYPE_num;
for ((*i) = 0; (*i) < some_get(x); (*i)++) {
some_fun(z, j);
}
我不确定从长远来看,还是建议不要这样做。
答案 0 :(得分:3)
关于可读性,我总是喜欢使用单独的循环计数器。
编辑:在这种情况下,斜体中的以下内容不正确,因为默认情况下C结构作为值副本传递到堆栈中,因此传递 j 循环到 some_fun()是可以的。但是,我将在此留下警告,因为它适用于许多类似的情况,其中结构或数组由指针值传递。 (又名“通过引用传递”)。
在您发布的代码中尤其如此,在该代码中,您以循环内的结构作为参数调用函数。 如果我不知道some_fun()的作用,则只能希望不会修改用作循环计数器的结构成员。希望不是战略。
因此,除非有其他特殊原因,否则我总是将可读性放在首位。请记住:如果您编写的代码受自己的语法和语义功能的限制,那么调试此类代码将非常无聊,因为调试比编写(无用的)代码难一个数量级。 ;)
添加:您可以查看所有变体的反汇编。编译器可能会在此处进行很多优化,特别是如果它可以“看到” some_fun()。