c - 使用结构字段作为循环计数器?

标签 c for-loop struct unions readability

问题的一些背景

如果我有这样的结构

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 header 以使用 idx.val.num 而不是 ?

为此,假设 idx_type 是字符串和数字类型的枚举,所有其他字段都有宏,但我只打算使用 IDX_NUM 宏,因为我不担心与 idx.type 有任何关系。

总结一下我的担忧:

  1. 它可读吗?我不想留下一团乱糟糟的东西,以至于有人会阅读并摇头......
  2. 是否建议不要这样做?
  3. 以下哪个是最佳解决方案?

结构字段作为循环计数器

#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 field/macro 扩展并复杂化了 for 循环 header ,但它仍然是相当容易理解的。

用原始计数器修改结构

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);
} 

我不确定从长远来看这会有多好,或者是否建议不要这样做。

最佳答案

至于可读性,我总是更喜欢单独的循环计数器。

编辑:斜体中的以下内容在这种特定情况下是不正确的,因为默认情况下 C 结构作为值副本在堆栈上传递,因此传递 j 到循环中的 some_fun() 就可以了。但我会在这里留下警告,因为它适用于许多类似的情况,在这些情况下,结构或数组由指针值传递。 (又名“通过引用传递”)。

在您发布的代码中尤其如此,您在其中调用一个函数并将结构作为循环内的参数。 如果我不知道 some_fun() 的作用,我只能希望我用作循环计数器的结构成员没有被修改。希望不是一种策略。

因此,除非有非常充分的理由不这样做,否则我总是将可读性放在首位。请记住:如果您编写的代码超出了您自己的语法和语义能力的极限,那么调试此类代码将毫无乐趣,因为调试比编写(错误的)代码难一个数量级。 ;)

补充:您可以查看所有变体的反汇编。编译器可能会在这里做很多优化,特别是如果它可以“看到”some_fun()。

关于c - 使用结构字段作为循环计数器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53537164/

相关文章:

c++ - 为什么给数组中的第一个元素赋值时必须指定索引号?

c++ - 使用双向链表实现稀疏矩阵中的多项式

javascript - For循环影响递归变量

c++ - 为什么结构体的 sizeof 不等于每个成员的 sizeof 之和?

c - C语言编程中的插入排序

c - 在 C 中转发可变参数函数的调用

c++ - 难以理解此 for 循环中的增量

linux - 使用for循环将文件从子目录移动到父目录

c- 在函数中分配结构成员时出错

c - 当我尝试向我的结构添加变量时出现段错误