2011-11-09 42 views
16

Nó chỉ ra rằng char c[] = {"a"}; là hoàn toàn hợp lệ trong cả hai C++03C++11.Tại sao trình khởi tạo có chứa một chuỗi ký tự hợp lệ để khởi tạo mảng `char`?

Tôi không mong đợi nó được, bởi vì nó là một mảng của char không phải của char const*, và tôi mong đợi một brace-initialiser để yêu cầu một loại tương thích cho mỗi "mặt hàng" của nó. Nó có một mục và đó là một số char const* không phải là char.

Vậy điều gì làm cho việc khởi tạo này hợp lệ? Và có lý do nào cho việc đó không?


Tương tự, char c[] = {"aa"}; biên dịch và in c kết quả ở đầu ra "aa".

tôi sẽ mong đợi char c[]{"a"} mới có giá trị trong C++ 11, tất nhiên, nhưng nó không giống nhau! Tương tự, char c[] = {'a'} hiển nhiên trong cả hai, như là char c[] = "a".

+0

Bạn đã thử 'char c [] = {" aa "};'? –

+0

@VJo: Cũng hợp lệ. –

+0

Tại sao bạn mong đợi nó không hợp lệ? Nó không thực sự rõ ràng những gì bạn đang yêu cầu. Nó hợp lệ vì không có quy tắc nào cấm nó. Bạn sẽ cấm quy tắc nào? – jalf

Trả lời

3

Loại vô hướng cũng có thể được khởi tạo bằng niềng răng (giống như cấu trúc và mảng).

struct S { int x, char c }; 
S s = {5, 'a'}; 

int arr[] = {5, 6, 7}; 

/* (my guess) out of consistency */ 
int z = { 4 }; 

Và kể từ xâu thể được gán cho char mảng và con trỏ

char arr[] = "literal"; 
char* ptr = "another"; 

Có vẻ như phù hợp để cho phép char arr[] = { "literal" }; quá.

+0

Aha! Tôi nghĩ nó có nghĩa. Vì vậy, tôi đã nhận được treo lên trên initialiser tổng hợp, khi thực sự nó là một một vô hướng? (Nếu bạn nhận được trôi dạt của tôi) Chúng tôi đang "xem" các chữ như một loại vô hướng? –

+0

Vâng, ít nhất đó là cách tôi nghĩ nó có nguồn gốc. Nhưng tôi không ở trong ủy ban tiêu chuẩn C :) Chỉ cần đoán ... – Pieter

+0

Được rồi; cảm ơn! –

5

Mặc dù nó có thể không nhất thiết phải trực quan, nó chỉ đơn giản là được phép; có một quy tắc riêng biệt cho nó ở cả hai tiêu chuẩn:

[2003: 8.5.2/1]:A char array (whether plain char , signed char , or unsigned char) can be initialized by a string-literal (optionally enclosed in braces); a wchar_t array can be initialized by a wide string-literal (optionally enclosed in braces); successive characters of the string-literal initialize the members of the array. [..]

[n3290: 8.5.2/1]:A char array (whether plain char , signed char , or unsigned char), char16_t array, char32_t array, or wchar_t array can be initialized by a narrow character literal, char16_t string literal, char32_t string literal, or wide string literal, respectively, or by an appropriately-typed string literal enclosed in braces. Successive characters of the value of the string literal initialize the elements of the array.

Tôi không thể giải thích lý do vì sao ủy ban đã thực hiện theo cách này.

+0

Vâng, đó là một liên lạc tốt đẹp.Bây giờ bạn có thể viết 'char a [] =" abc ";', 'char b [] = {" abc "};', và 'char c [] {" abc "};' ... –

+0

@KerrekSB: Tôi không thấy nó hữu ích như thế nào! –

+0

'Tôi không thể giải thích tại sao ủy ban làm theo cách này, mặc dù' Bạn có thể thêm câu hỏi đó vào Câu hỏi vì câu hỏi đó vẫn chưa được trả lời. Có thể nói, Hầu hết các câu trả lời đều nói 'Vì tiêu chuẩn nói vậy' nhưng có lẽ có một số câu trả lời hay mà chỉ có thể nói 'tại sao?' –

0

Tôi đoán tính năng này tương thích với C? Trên thực tế, T x = { value of T }; cũng áp dụng cho các loại T khác. Trong tiêu chuẩn C99,

6.7.8/11: The initializer for a scalar shall be a single expression, optionally enclosed in braces.

6.7.8/14: An array of character type may be initialized by a character string literal, optionally enclosed in braces.

6.7.8/15: An array with element type compatible with wchar_t may be initialized by a wide string literal, optionally enclosed in braces.

Tôi không biết tại sao C có mặc dù vậy.

+0

Âm mưu dày đặc. –

+0

Đối với câu thứ hai, ý của bạn là gì? 'int main() {int i = 3; int * ptr = & i; int x [] = {ptr}; } '->' lỗi: chuyển đổi không hợp lệ từ 'int *' sang 'int'' (như mong đợi, và như tôi dự kiến ​​ban đầu với 'char' ... không phải là việc sử dụng một con trỏ ở đây là tất cả tương đương với một chữ dù sao, nhưng bạn biết ý tôi là ... Tôi khá chắc chắn đó là một trường hợp đặc biệt cho 'char'). [sửa đổi: đừng bận tâm; chỉ cần nhận ra toàn bộ báo giá làm rõ những gì bạn nói, chính xác. Tôi đã nói "loại" thay vì "loại" :)] –

+0

@ TomalakGeret'kal: Tôi chỉ có nghĩa là 'int * x = {ptr};'. Một con trỏ không thể được chuyển đổi hoàn toàn thành một mảng. Và chuỗi ký tự là một loại mảng (§6.4.5). – kennytm

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