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=1
và z=2
trên cả hai hệ thống Linux và Windows?
typedef enum {
x,
y,
z
} someName;
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=1
và z=2
trên cả hai hệ thống Linux và Windows?
typedef enum {
x,
y,
z
} someName;
Câu trả lời:
Đú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 đó.
[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."
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.
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'.
'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
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.