Czy domyślne wartości wyliczenia w języku C są takie same dla wszystkich kompilatorów?
107
Podczas deklarowania enum, jak pokazano poniżej, nie wszystkie kompilatory C ustawić domyślne wartości jak x=0, y=1i z=2na obu systemach Linux i Windows?
Tak, wymagają tego normy i jestem pewien, że ktoś będzie mógł je zacytować.
Nemo
Odpowiedzi:
115
Tak. O ile nie określisz inaczej w definicji wyliczenia, początkowy moduł wyliczający zawsze ma wartość zero, a wartość każdego kolejnego modułu wyliczającego jest o jeden większy niż poprzedni moduł wyliczający.
i to identyczne zachowanie jest wymagane zarówno przez C, jak i C ++. W C ++ jest to [dcl.enum]: „Jeśli pierwszy moduł wyliczający nie ma inicjatora, wartość odpowiadającej mu stałej wynosi zero. Definicja modułu wyliczającego bez inicjatora daje modułowi wyliczającemu wartość uzyskaną przez zwiększenie wartości poprzedniego modułu wyliczającego o jeden”.
Ben Voigt
3
Tak, a także w innych językach, które zaczynają się na literę C, na przykład C #.
James McNellis
70
C99 Standard
Wersja robocza N1265 C99 zawiera tekst 6.7.2.2/3 „Specyfikatory wyliczenia”
Moduł wyliczający z = definiuje stałą wyliczenia jako wartość wyrażenia stałego. Jeśli pierwszy moduł wyliczający ma no =, wartość jego stałej wyliczania wynosi 0. Każdy kolejny moduł wyliczający z no = definiuje swoją stałą wyliczania jako wartość wyrażenia stałego uzyskanego przez dodanie 1 do wartości poprzedniej stałej wyliczenia. (Użycie modułów wyliczających z = może generować stałe wyliczenia z wartościami, które powielają inne wartości w tym samym wyliczeniu).
W przypadku zgodnych implementacji zawsze obowiązują następujące zasady:
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);return0;}
Jeśli pierwsza wartość zmiennej wyliczeniowej nie zostanie zainicjowana, kompilator C automatycznie przypisuje wartość 0. Kompilator kontynuuje zwiększanie wartości poprzedniej zmiennej wyliczeniowej o 1.
Na przykład:
enum months{jan,feb,mar}
Wyjaśnienie: wartość jan będzie wynosić 0, luty będzie wynosić 1, mar będzie wynosić 2.
enum months{jan=123,feb=999,mar}
Wyjaśnienie: wartość Jan będzie wynosić 123, luty 999, mar będzie wynosić 1000.
enum months{jan='a',feb='s',mar}
Objaśnienie: Wartość jan to „a”, feb - „s”, mar - „t”.
Zastanów się, jak Twoja odpowiedź dodaje się do puli odpowiedzi. To znaczy, w jaki sposób twoja nowa odpowiedź (5 lat później) dodaje coś nowego, czego nie ma w innej odpowiedzi? Na pierwszy rzut oka wydaje się, że zawiera mniej informacji niż pozostałe dwie odpowiedzi.
LawfulEvil
2
Ehhh @LawfulEvil relaks. Wiele odpowiedzi daje ludziom, którzy patrzą na to w przyszłości, wiele perspektyw. To powiedziawszy, jest to źle sformatowana, pozbawiona informacji odpowiedź, ale obszerne odpowiedzi same w sobie nie są złe.
Odpowiedzi:
Tak. O ile nie określisz inaczej w definicji wyliczenia, początkowy moduł wyliczający zawsze ma wartość zero, a wartość każdego kolejnego modułu wyliczającego jest o jeden większy niż poprzedni moduł wyliczający.
źródło
[dcl.enum]
: „Jeśli pierwszy moduł wyliczający nie ma inicjatora, wartość odpowiadającej mu stałej wynosi zero. Definicja modułu wyliczającego bez inicjatora daje modułowi wyliczającemu wartość uzyskaną przez zwiększenie wartości poprzedniego modułu wyliczającego o jeden”.C99 Standard
Wersja robocza N1265 C99 zawiera tekst 6.7.2.2/3 „Specyfikatory wyliczenia”
W przypadku zgodnych implementacji zawsze obowiązują następujące zasady:
main.c
Skompiluj i uruchom:
Przetestowano w Ubuntu 16.04, GCC 6.4.0.
źródło
Jeśli pierwsza wartość zmiennej wyliczeniowej nie zostanie zainicjowana, kompilator C automatycznie przypisuje wartość 0. Kompilator kontynuuje zwiększanie wartości poprzedniej zmiennej wyliczeniowej o 1.
Na przykład:
Wyjaśnienie: wartość jan będzie wynosić 0, luty będzie wynosić 1, mar będzie wynosić 2.
Wyjaśnienie: wartość Jan będzie wynosić 123, luty 999, mar będzie wynosić 1000.
Objaśnienie: Wartość jan to „a”, feb - „s”, mar - „t”.
źródło
't'
jest to gwarantowane, mogą istnieć zestawy znaków, w których litery nie są w kolejności alfabetycznejTak, wartość wyliczenia bydefult zaczyna się od 0 do n-tego elementu na dowolnej platformie.
źródło