C中的默认枚举值是否对所有编译器都相同?


107

当声明枚举,如下图所示,做所有的C编译器设置的默认值x=0y=1以及z=2在Linux和Windows系统?

typedef enum {
    x,
    y,
    z
} someName;

3
是的,这是标准所要求的,我相信有人可以引用它们。
Nemo

Answers:


115

是。除非在枚举的定义中另外指定,否则初始枚举器的值始终为零,并且每个后续枚举器的值都比前一个枚举器大1。


14
并且,C和C ++都需要这种相同的行为。在C ++中,它是[dcl.enum]:“如果第一个枚举器没有初始化程序,则相应常数的值为零。不带初始化程序的枚举器定义将通过将前一个枚举器的值加1而获得的值赋予枚举器。”
Ben Voigt

3
是的,还有其他以字母C开头的语言,例如C#。
James McNellis

70

C99标准

N1265 C99草案说,在6.7.2.2/3“枚举符”

带有=的枚举数将其枚举常量定义为常量表达式的值。如果第一个枚举数为no =,则其枚举常数的值为0。每个后续的no =的枚举数都将其枚举常数定义为将前一个枚举常数的值加1所得的常数表达式的值。(将枚举数与=一起使用可能会产生枚举常量,其值与同一枚举中的其他值重复。)

因此,以下始终适用于符合标准的实现:

main.c

#include <assert.h>
#include <limits.h>

enum E {
    E0,
    E1,
    E2 = 3,
    E3 = 3,
    E4,
    E5 = INT_MAX,
#if 0
    /* error: overflow in enumeration values */
    E6,
#endif
};

int main(void) {
    /* If unspecified, the first is 0. */
    assert(E0 == 0);
    assert(E1 == 1);
    /* Repeated number, no problem. */
    assert(E2 == 3);
    assert(E3 == 3);
    /* Continue from the last one. */
    assert(E4 == 4);
    assert(E5 == INT_MAX);
    return 0;
}

编译并运行:

gcc -std=c99 -Wall -Wextra -pedantic -o main.out main.c
./main.out

已在Ubuntu 16.04,GCC 6.4.0中测试。


7

如果enum变量的第一个值未初始化,则C编译器会自动将值分配为0.编译器会继续将先前的enum变量的值增加1。

例如:

enum months{jan,feb,mar}

说明:jan的值将为0,feb的值为1,mar的值为2。

enum months{jan=123,feb=999,mar}

说明:jan的值将为123,feb的值为999,mar的值为1000。

enum months{jan='a',feb='s',mar}

说明:jan的值为'a',feb的值为's',mar的值为't'。


1
三月的存在't'不能保证,就不可能有字符集,其中的字母不连续字母顺序排列
MM

-15

是的,枚举值默认从0到第n个元素开始到任何平台。


14
考虑一下您的答案如何添加到答案池中。也就是说,您的新答案(五年后)如何添加其他答案未涵盖的新内容?乍一看,它似乎比其他两个答案提供的信息少。
LawfulEvil

2
恩@LawfulEvil放松。多种答案使人们在将来有多种观点。就是说,这是一个格式不正确,信息不充分的答案,但是足够多的答案本身也不错。
肯尼·沃登18'Mar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.