2012-01-06 15 views
6

Thông thường khi sử dụng một tuyên bố switch, bạn không thể xác định khởi tạo các biến địa phương để báo cáo kết quả hợp chất, nhưBiến cục bộ trong câu lệnh chuyển đổi phức hợp được khởi tạo khi nhãn `mặc định:` được đặt ngoài dấu ngoặc ôm?

switch (a) 
{ 
    int b = 5; /* Initialization is skipped, no matter what a is */ 

    case 1: 
    /* Do something */ 
    break; 
    default: 
    /* Do something */ 
    break; 
} 

Tuy nhiên, kể từ khi tuyên bố switch là một tuyên bố như for hoặc while, không có quy tắc chống lại không sử dụng câu lệnh ghép, look here for examples. Nhưng điều này có nghĩa là, một nhãn có thể được sử dụng giữa dấu ngoặc đơn đóng sau từ khóa switch và dấu ngoặc mở.

Vì vậy, theo ý kiến ​​của tôi, nó sẽ có thể và được phép sử dụng một tuyên bố switch như thế này:

switch (a) 
    default: 
{ 
    int b = 5; /* Is the initialization skipped when a != 1? */ 
    /* Do something for the default case using 'b' */ 
    break; 

    case 1: // if a == 1, then the initialization of b is skipped. 
    /* Do something */ 
    break; 
} 

Câu hỏi của tôi: Sản phẩm khởi nhất thiết thực hiện trong trường hợp này (a = 1!)? Từ những gì tôi biết về các tiêu chuẩn, có, nó nên được, nhưng tôi không thể tìm thấy nó trực tiếp trong bất kỳ tài liệu tôi có sẵn. Bất cứ ai có thể cung cấp một câu trả lời kết luận?

Và trước khi tôi nhận được nhận xét về hiệu ứng đó, vâng, tôi biết đây không phải là cách để lập trình trong thế giới thực. Nhưng, như mọi khi, tôi quan tâm đến ranh giới của đặc tả ngôn ngữ. Tôi không bao giờ chịu đựng được phong cách như vậy trong nhóm lập trình của tôi!

+0

@Mat Không, đó chỉ là ý tưởng: Nhãn trong câu lệnh 'switch' có thể xuất hiện sau dấu ngoặc đơn cho đến cuối câu lệnh (thường là hợp chất), vì vậy nhãn' default: 'bên ngoài dấu ngoặc đơn sẽ là IMHO hợp pháp . Khó hiểu, vâng, chắc chắn! Nhưng không thiếu niềng răng. –

+1

Vì vậy, bạn có hỏi liệu 'b' có hợp lệ không nếu' trường hợp 1' được lấy? Điều này thực sự không khác với 'goto foo; {int b = 5; foo: ...} '. –

+0

Ok, điều đó chắc chắn khó hiểu ... – Mat

Trả lời

7

Hầu hết mọi người đều nghĩ về một số liệu là switch, nhưng về mặt kỹ thuật được tính toán goto. Và case <cte>:default: thực sự là nhãn. Vì vậy, các quy tắc của goto được áp dụng trong những trường hợp này.

Cả hai ví dụ của bạn đều hợp pháp về cú pháp, nhưng trong ví dụ thứ hai, khi a==1 khởi tạo b sẽ bị bỏ qua và giá trị của nó sẽ không được xác định. Không có vấn đề miễn là bạn không sử dụng nó.

THAM KHẢO:

Theo tiêu chuẩn C99, 6.2.4.5, liên quan đến các biến tự động:

Nếu một khởi được Speci fi ed cho đối tượng, nó được thực hiện mỗi lần tuyên bố đạt được trong việc thực thi khối;

Vì vậy, biến được khởi tạo mỗi lần luồng thực hiện đạt đến khởi tạo, giống như khi nó được gán. Và nếu bạn nhảy qua khởi tạo lần đầu tiên, thì biến sẽ không được khởi tạo.

+0

Nhưng 'b' được bảo đảm được khởi tạo khi' a! = 1'? –

+0

_No_ trong ví dụ đầu tiên của bạn; _yes_ trong giây phút thứ hai của bạn. Vui lòng xem tham chiếu đến tiêu chuẩn trong câu trả lời được cập nhật. – rodrigo

Các vấn đề liên quan