Các giá trị enum mặc định trong C có giống nhau cho tất cả các trình biên dịch không?


107

Khi tuyên bố một enum như hình dưới đây, làm tất cả các trình biên dịch C thiết lập các giá trị mặc định là x=0, y=1z=2trên cả hai hệ thống Linux và Windows?

typedef enum {
    x,
    y,
    z
} someName;

3
Vâng, nó được yêu cầu bởi các tiêu chuẩn, và tôi chắc chắn rằng ai đó sẽ có thể trích dẫn chúng.
Nemo

Câu trả lời:


115

Đúng. Trừ khi bạn chỉ định khác trong định nghĩa về kiểu liệt kê, thì điều tra viên ban đầu luôn có giá trị bằng không và giá trị của mỗi điều tra viên tiếp theo lớn hơn một điều tra viên trước đó.


14
và, hành vi giống hệt nhau này được yêu cầu bởi cả C và C ++. Trong C ++, đó là [dcl.enum]: "Nếu điều tra viên đầu tiên không có bộ khởi tạo, giá trị của hằng số tương ứng bằng 0. Định nghĩa điều tra viên không có bộ khởi tạo sẽ cung cấp cho người điều tra giá trị thu được bằng cách tăng giá trị của điều tra viên trước đó lên một."
Ben Voigt

3
Có, và cả các ngôn ngữ khác bắt đầu bằng chữ C, như C #.
James McNellis

70

Tiêu chuẩn C99

Bản nháp N1265 C99 cho biết ở 6.7.2.2/3 "Bộ chỉ định liệt kê"

Một điều tra viên với = xác định hằng số liệt kê của nó là giá trị của biểu thức hằng số. Nếu điều tra viên đầu tiên không có =, giá trị của hằng số liệt kê của nó là 0. Mỗi điều tra viên tiếp theo có không = xác định hằng số liệt kê của nó là giá trị của biểu thức hằng thu được bằng cách thêm 1 vào giá trị của hằng số liệt kê trước đó. (Việc sử dụng các kiểu liệt kê với = có thể tạo ra các hằng số kiểu liệt kê với các giá trị trùng lặp với các giá trị khác trong cùng một kiểu liệt kê.)

Vì vậy, những điều sau đây luôn tuân theo việc triển khai tuân thủ:

C chính

#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;
}

Biên dịch và chạy:

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

Đã thử nghiệm trong Ubuntu 16.04, GCC 6.4.0.


7

Nếu giá trị đầu tiên của biến enum không được khởi tạo thì trình biên dịch C sẽ tự động gán giá trị 0. Trình biên dịch tiếp tục tăng giá trị của biến enum trước đó lên 1.

Ví dụ:

enum months{jan,feb,mar}

Giải thích: Giá trị của jan sẽ là 0, feb sẽ là 1, mar sẽ là 2.

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

Giải thích: Giá trị của jan sẽ là 123, feb sẽ là 999, mar sẽ là 1000.

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

Giải thích: Giá trị của jan sẽ là 'a', feb sẽ là 's', mar sẽ là 't'.


1
mar 't'không được đảm bảo, có thể có các bộ ký tự trong đó các chữ cái không theo thứ tự bảng chữ cái liên tiếp
MM

-15

Có, giá trị enum bydefult bắt đầu từ 0 đến n'th phần tử cho bất kỳ nền tảng nào.


14
Xem xét cách câu trả lời của bạn thêm vào nhóm câu trả lời. Đó là, làm thế nào để câu trả lời mới của bạn (5 năm sau) thêm một cái gì đó mới mà không được đề cập trong một câu trả lời khác? Thoạt nhìn, nó có vẻ ít thông tin hơn hai câu trả lời còn lại.
LawfulEvil

2
Ehhh @LawfulEvil thư giãn. Nhiều câu trả lời cung cấp cho mọi người nhìn vấn đề này trong tương lai nhiều góc độ. Điều đó nói rằng, đây là một câu trả lời có định dạng kém, không thông tin, nhưng các câu trả lời phong phú và bản thân nó không tệ.
Kenny Worden
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.