【问题标题】:C - Pros/Cons of Enum-Indexed Arrays [closed]C - 枚举索引数组的优点/缺点 [关闭]
【发布时间】:2012-10-26 18:33:54
【问题描述】:

根据我的经验,现实世界很少提供非负整数索引。许多事情甚至没有用数字表示。并且许多具有数字表示索引的事物的索引不是从 0 开始的。为什么我们仍然局限于整数索引数组?

也许我错了,但似乎枚举索引数组通常比数字索引数组更合适(因为枚举通常更准确,“真实世界”表示)。虽然枚举通常可以相对容易地转换为 C 样式的数组索引...

enum Weekday = {
    SUNDAY,
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY
}

// hopefully C doesn't allow nonsequential enum values; else pray to God
// no one does something like setting Sunday = 4 and Saturday = 4096
int numberOfDays = Saturday-Sunday+1;

int hoursWorkedPerDay[numberOfDays];

hoursWorkedPerDay[(int)SUNDAY] = 0;
hoursWorkedPerDay[(int)MONDAY] = 8;
hoursWorkedPerDay[(int)TUESDAY] = 10;
hoursWorkedPerDay[(int)WEDNESDAY] = 6;
hoursWorkedPerDay[(int)THURSDAY] = 8;
hoursWorkedPerDay[(int)FRIDAY] = 8;
hoursWorkedPerDay[(int)SATURDAY] = 0;

...我们仍然需要保持枚举数量和数组大小之间的一致性(但是,这不是一个糟糕的解决方案,因为“SUNDAY”没有比 0 更有效的整数映射),更重要的是,任何可以转换为 int 的东西仍然可以放入索引来操作数组:

// continued from above
void resetHours (void) {
    int i = 0;
    int hours = 0;
    for (i = 0; i<numberOfDays; i++) {
        hoursWorkedPerDay[hours] = i;
        // oops, should have been: "...[i] = hours;"
        // an enum-indexed implementation would have caught this
        // during compilation
    }
}

此外,从 enum 到 int 的整个转换是一整层的复杂性,似乎没有必要。

有人可以解释一下枚举索引是否有效,并列出每种方法的优缺点吗?如果存在这样的信息,为什么 C 标准中缺少一个看似有用的特性?

【问题讨论】:

  • "希望 C 不允许非顺序枚举值;" enum 值。)
  • 感谢上帝。否则,您将如何实现一个用作位掩码的枚举?
  • 这是字典的另一种实现——将属性键(枚举索引)转换为属性值(表值)。
  • 在 C++11 中有一个从 enum 到 int 的整数提升,用于具有固定基础类型的无范围枚举 (§4.6/4 conv.prom)。
  • 您应该专注于 C 或 C++ 或将其拆分为 2 个问题。每种语言都有不同的答案。

标签: c++ c arrays enums indexing


【解决方案1】:
Sunday =0 //by default, if you won't mention explicit value then it would take 0

Saturday = 6 // as in your example

所以

int numberOfDays = Saturday-Sunday; // which is 6 

int hoursWorkedPerDay[numberOfDays]; 

数组将只有 6 个位置来保存值。

hoursWorkedPerDay[(int)SUNDAY] = 0;
hoursWorkedPerDay[(int)MONDAY] = 8;
hoursWorkedPerDay[(int)TUESDAY] = 10;
hoursWorkedPerDay[(int)WEDNESDAY] = 6;
hoursWorkedPerDay[(int)THURSDAY] = 8;
hoursWorkedPerDay[(int)FRIDAY] = 8;
hoursWorkedPerDay[(int)SATURDAY] = 0;  

访问数组索引(即 6)是未定义的行为

【讨论】:

  • 我在我的例子中就是这样做的......
  • 阅读我答案的最后一行.. 你确实做到了,这就是为什么它是未定义的行为
  • 我在哪里尝试访问大于 6 的索引?此外,索引越界行为并不是我的观点,但它确实表明枚举索引数组不必担心这一点。
  • 您没有正确看到我的答案。您创建了大小为 6 的数组,因此您无法访问 a[6],因为 5 是最后一个有效索引,之后访问是未定义的行为。我想你明白
  • hoursWorkedPerDay[(int)SATURDAY] = 0; //这条线是什么意思? Saturady 是 6 对吗?
【解决方案2】:

如果你真的想使用枚举作为索引,你应该明确声明整数值。

另一方面,我个人更喜欢 s.th。类型安全(即没有丑陋的演员表,甚至可能没有必要),例如:

std::map<Weekday,int> hoursWorkedPerDay;

【讨论】:

    猜你喜欢
    • 2011-01-20
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-06
    • 1970-01-01
    相关资源
    最近更新 更多