你能通过结构中的值枚举吗?

时间:2012-03-04 15:51:04

标签: c

我知道在定义一个枚举时,你可以用数字列表列表:

typedef enum MONTH { Jan = 1, Feb, March, ... };

你能以同样的方式枚举结构中的值吗?我基本上想要使用for或while循环遍历struct中的值。

struct items {char *item_name, int item_value};

struct items Items_list[] =
{ 
    "item 1", 2000,
    "item 2", 3600,
    ....
};

使用的语言是C.

编辑:我可能刚刚回答了我自己的问题,因为我想到的是一系列结构。不过现在还会提出这个问题。

4 个答案:

答案 0 :(得分:3)

此声明和初始化程序组合无效。在撰写此答案的原始版本时问题已更改。

如果你问“有没有办法访问结构的第一个成员,那么第二个,而不知道结构元素名称”,那么答案是'不,事先没有仔细编码'。


仔细编码涉及多个步骤。对于每个元素,您需要一个类型的编码,结构中成员的偏移量,以及成员的大小(如果该类型的编码无论如何都不会给您):

typedef enum { MT_INT, MT_CHAR_PTR, ... } MemberType;

typedef struct MemberAccess
{
    const char *name;
    size_t      offset;
    MemberType  type;
} MemberAccess;

static const MemberAccess members[] =
{
    "item_name",  offsetof(struct items, item_name),  MT_CHAR_PTR },
    "item_value", offsetof(struct items, item_value), MT_INT      },
};

现在,您可以编写代码来获取或设置特定指针指向的struct item的第N个成员中的值。但是,这样做仍然远非微不足道。

int get_int(const void *data, const MemberAccess *member)
{
    assert(member->type == MT_INT);
    return (*(const int *)((const char *)data + member->offset));
}

GCC尽管如此,你需要将角色转换为角色指针;你无法在void *上合法地进行指针算术。

然后您可以调用:

int value = get_int(&Items_list[1], &members[1]);

获取数组第二个元素的第二个字段的整数值。

这是非常难以理解的,必须有充分的理由来解决这些问题。可能有这样的原因。我知道一个具有400个配置参数的系统(这本身就是一个问题,但是我们假设它已经存在;它们已经积累了20多年的开发时间)存储在具有异构类型的结构中。操纵它的代码被写出400次 - 哎哟! - 因为它不使用从MemberAccess结构的模拟驱动的系统。代码将比目前更紧凑,因为有大约十几种数据类型需要处理,因此大多数代码都是重复的。另一种降低代码复杂性的方法是将所有内容都变成字符串,但这种转换也存在问题。

答案 1 :(得分:2)

不,你不能迭代struct的元素。您可以做的最好的事情是硬编码循环中struct的名称:

struct items *item = Items_list;

while (item < Items_list + sizeof(Items_list) / sizeof(*Items_list)) {
    printf("%s %d", item->item_name, item->item_value);
    ++item;
}

另请注意,您无法可靠地迭代enum,因为它可以像这样定义:

typedef enum MONTH { Jan = 1, Feb = 13, March = 10, ... };

元素既无序又无连续(即数字中存在间隙)。

答案 2 :(得分:1)

一种方法,当你在内部结构中有一个指针类型,并且当指针不能有意义地为NULL时,就是这样做:

for (int i=0; Item_List[i].item_name != 0; i++) {
   // do whatever
}

如果你没有方便的指针类型,那就是&#34; sentinel&#34;值通常可用于标记最后一条记录。

您需要记住在结构数组的末尾添加一个null元素/ sentinel,并修复您的语法。

答案 3 :(得分:0)

不,没有简单的方法可以做到这一点。结构不是数值,因此您无法遍历其值/成员。您可以使用数组而不是结构,并使用简单的for循环访问其成员,或者编写一个特殊的枚举器回调函数,该函数将struct作为其一个参数,一个数字作为另一个参数,并使用case或if语句,看起来结构的每个成员。