Чи однакові значення перерахунків за замовчуванням у C однакові для всіх компіляторів?


107

При оголошенні перерахування , як показано нижче, не всі компілятори C встановити значення за замовчуванням , як x=0, y=1і z=2в обох системах Linux і Windows?

typedef enum {
    x,
    y,
    z
} someName;

3
Так, цього вимагають стандарти, і я впевнений, що хтось зможе їх цитувати.
Немо

Відповіді:


115

Так. Якщо ви не визначите інше у визначенні перерахування, у початкового нумератора завжди є нульове значення, а значення кожного наступного нумератора на одне більше, ніж попереднє перерахування.


14
і ця однакова поведінка вимагається як C, так і C ++. У C ++ це [dcl.enum]: "Якщо у першого обчислювача немає ініціалізатора, значення відповідної константи дорівнює нулю. Описання перелічувача без ініціалізатора надає перерахувачу значення, отримане шляхом збільшення значення попереднього нумератора на одиницю."
Бен Войгт

3
Так, а також інші мови, які починаються з літери C, як, наприклад, C #.
James McNellis

70

C99 Стандарт

У чернетці N1265 C99 написано в 6.7.2.2/3 "Специфікатори перерахування"

Чисельник з = визначає свою константу нумерації як значення постійного виразу. Якщо першого обчислювача немає =, значення його постійної нумерації дорівнює 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'це не гарантується, можуть бути набори символів, у яких букви не є в алфавітному порядку
ММ

-15

Так, значення перерахунку bydefult починається від 0 до n-го елемента до будь-якої платформи.


14
Поміркуйте, як ваша відповідь додає до групи відповідей. Тобто, як ваша нова відповідь (через 5 років) додає щось нове, що не стосується іншої відповіді? На перший погляд, це здається менш інформативним, ніж два інших відповіді.
LawfulEvil

2
Ehhh @ LawfulEvil розслабись. Кілька відповідей дають людям, які дивляться на це у майбутньому, чимало перспектив. Однак це погана форматована неінформативна відповідь, але досить відповіді самі по собі не є поганими.
Кенні Worden
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.