【问题标题】:Enum user-defined data-type in C programmingC编程中的枚举用户定义数据类型
【发布时间】:2019-12-26 16:23:51
【问题描述】:

我正在研究enum,即C 中的关键字,用于定义枚举数列表,也称为枚举常量,编译器会为其分配有符号整数值。

Syntax:
enum identifier (optional) { enumerator-list }

我正在玩 enum 以了解编译器如何将整数分配给枚举列表中的枚举常量。

因此,当我使用enum 编写如下 3 个不同的程序时,我遇到了一些问题,这些问题都附在下面的每个程序中。

程序-1

#include <stdio.h>
#include <inttypes.h>

enum days_of_week {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};

int main(void) {
    printf("%u %u %u %u %u %u %u\n", Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday);
    return 0;
}

Output: 0 1 2 3 4 5 6,因为当没有为枚举常量显式分配整数时,编译器会自动根据zero-based indexing索引这些枚举常量。

程序-2

#include <stdio.h>
#include <inttypes.h>

enum days_of_week {Sunday, Monday, Tuesday = UINT16_MAX, Wednesday, Thursday, Friday, Saturday};

int main(void) {
    printf("%u %u %u %u %u %u %u\n", Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday);
    return 0;
}

Output: 0 1 65535 65536 65537 65538 65539,因为我已经将UINT16_MAX分配给Tuesday,在此之前,编译器在zero-based indexing的基础上将整数分配给枚举常量,在Tuesday之后,它根据Tuesday将整数分配给枚举常量分配给其前一个枚举常量 + 1 的整数。

程序-3

#include <stdio.h>
#include <inttypes.h>

enum days_of_week {Sunday, Monday, Tuesday = UINT32_MAX, Wednesday, Thursday, Friday, Saturday};

int main(void) {
    printf("%u %u %u %u %u %u %u\n", Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday);
    return 0;
}

编译器gcc 7.4.0 抛出一个错误,

enum_example_1.c:8:58: error: overflow in enumeration values
enum days_of_week {Sunday, Monday, Tuesday = UINT32_MAX, Wednesday, Thursday, Friday, Saturday};
  • 由此得出结论,我可以分配给这些枚举常量的最大整数是UINT16_MAX,但我有一个问题,这个值是否依赖于编译器/系统?

  • 编译器在哪一步将这些整数值分配给这些枚举器,我的意思是编译器是在编译时还是运行时分配这些值?

使用enum 优于宏的优点是:

  • 它增加了源代码的可读性。
  • 范围规则适用于enum,但不适用于宏。
  • 它会自动将有符号整数初始化为枚举器列表中的枚举器常量/标记。

除了上面列出的优点之外,使用enum 的其他优点是什么,以及在哪些用例中使用enums 优于宏?

【问题讨论】:

  • 错误不是将UINT32_MAX分配给Tuesday,而是将UINT32_MAX + 1分配给Wednesday
  • "编译器是在编译时还是运行时分配这些值" - 编译器本身只在编译时出现,所以它决定在编译时分配什么值.
  • 在您的特定编译器中,使用您的特定标志,是的。标准(see C11 p6.7.2.2)只要求“常量的类型与 char、有符号整数类型或无符号整数类型兼容”
  • Cenumenumcppreference 上有很好的解释/讨论。
  • @striker 不,在你的实现中最大值是INT32_MAX,因为枚举是有符号的整数值。您应该使用%d(而不是%u)来打印分配给枚举常量的值。

标签: c enums


【解决方案1】:

我修改了程序 1 以突出显示如何使 enumlocal array 一起使用的更具体的编程技术,如下所示:

#include <stdio.h>
#include <string.h>
#include <inttypes.h>

enum days_of_week {Sunday = 3488, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};

const char *getDayOfWeek(unsigned int day);
const char *getDayOfWeek(unsigned int day) {
    static const char *days[7] = {
        "Sunday",
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday"
    };
    day -= 3488;
    day %= 7;
    return days[day];
}

int main(void);
int main() {
    static unsigned int day = (unsigned int) Thursday;

    printf("%X %X %X %X %X %X %X\n", Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday);

    if (day >= Sunday && day <= Saturday) {
        printf("The day of week is: %s (or %X).\n", getDayOfWeek(day), day);
    }

    return 0;
}

查看链接:https://ideone.com/IY39lR

【讨论】:

  • 1.这个问题的答案是什么? -- 2. 你如何确保枚举名称和字符串内容匹配? -- 3. 为什么不减去Sunday 而不是在别处定义的幻数?
  • 因为这些hexadecimal characters 是单词“DAY”或“DA”的可打印部分加上“DA0”的“0”到“6”的数组索引...' DA6'(见,3488 = DA0 = “星期日”,3489 = DA1 = “星期一”,3490 = DA2 = “星期二”,3491 = DA3 = “星期三”,等等)。 您只需要指定此特定序列中的第一个数字
  • 当你的意思是十六进制时不要写十进制数。而且你没有回答我的任何问题。
  • 我有点脑子,所以对此我深表歉意。如果您愿意,我可以重做代码以显示重点...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-10
  • 1970-01-01
  • 2020-07-08
相关资源
最近更新 更多