2011-11-09 2 views
16

C++03C++11에서 모두 유효합니다.`char` 배열을 초기화하는데 유효한 문자열 리터럴을 포함하는 초기화 기는 왜입니까?

char이 아닌 char const*이 아니기 때문에 나는 기대하지 않을 것입니다. 그리고 brace-initialiser가 각 "items"에 대해 호환 가능한 유형을 요구할 것으로 기대합니다. 아이템이 하나 있는데 char const*이 아니라 char입니다.

그래서이 초기화가 유효합니까? 그리고 그렇게되는 이유가 있습니까?


마찬가지로 char c[] = {"aa"}; 컴파일하고 출력 "aa"의 결과 c 인쇄.

나는 char c[]{"a"} 물론, C++ 11에서 유효한 것으로 기대하지만 같은 아니에요! 마찬가지로, char c[] = {'a'}은 모두 char c[] = "a"과 같이 두 가지 모두에서 분명합니다.

+0

당신은'char c [] = { "aa"};'시도 했습니까? –

+0

@VJo : 유효합니다. –

+0

왜 그것이 유효하지 않다고 생각합니까? 당신이 묻고있는 것이 분명하지 않습니다. 그것을 금지하는 규칙이 없기 때문에 유효합니다. 어떤 규칙에 따라 그것을 금지 하시겠습니까? – jalf

답변

3

스칼라 유형은 중괄호 (structs 및 arrays처럼)를 사용하여 초기화 할 수도 있습니다.

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

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

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

그리고 문자열 리터럴 이후

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

너무 char arr[] = { "literal" }; 수 있도록 피팅 보인다 배열의 포인터를 숯불에 할당 할 수 있습니다.

+0

Aha! 나는 그것이 합리적이라고 생각한다. 그래서 저는 정말로 이니셜 라이저에 매달려있었습니다. 스칼라 일 때였습니까? (만약 당신이 내 표류를 얻는다) 우리는 리터럴을 일종의 스칼라로보고있다? –

+0

네, 적어도 그렇게 생각한 것입니다. 하지만 나는 C 표준위원회에 있지 않다. 그냥 추측하면 ... – Pieter

+0

좋아. 감사! –

5

비록 반드시 직관적 일 필요는 없지만 단순히 입니다. 위원회는이 방법으로 만든 이유가 있지만, 설명 할 수없는

[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.

: 모두 기준에 대한 별개의 규칙이있다.

+0

글쎄, 좋은 접촉이야.이제 char {[] = "abc";''char b [] = { "abc"};'와'char c [] { "abc"};'를 쓸 수 있습니다 ... –

+0

@KerrekSB : 그게 얼마나 유용한 지 모르겠다! –

+0

'위원회가 왜 이런 식으로 만들었는지 설명 할 수는 없지만, 질문에 대답을 덧붙일 수는 있습니다. 답 : 대부분의 대답은 '표준이 그렇게 말했기 때문에'라고 말할 것입니다. 무엇이 단지 이유를 말해 줄 수 있겠는가? –

0

C 호환성을위한 것 같습니까? 실제로 T x = { value of T };은 다른 유형의 T에도 적용됩니다. 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.

나는 C가 왜 이것을 가지고 있는지 모른다.

+0

플롯이 두껍습니다. –

+0

두 번째 문장의 의미는 무엇입니까? 'int main() {int i = 3; int * ptr = & i; int x [] = {ptr}; }'->'오류 : 'int *'에서 'int'로의 변환이 잘못되었습니다. (기대했던대로, 처음에는'char'로 기대했던 것처럼 ... 포인터의 사용은 리터럴에 해당합니다. 어쨌든, 당신은 내가 무슨 뜻인지 안다. 나는 char의 특별한 경우라고 확신한다.). [편집 : 신경 쓰지 마; 단지 전체 인용문이 귀하가 말한 내용을 정확하게 명료하게 알게되었습니다. 나는 "유형"보다는 "종류"라고 말했을 것이다.]] –

+0

@ TomalakGeret'kal : 나는 단지'int * x = {ptr};를 의미한다. 포인터는 암시 적으로 배열로 변환 될 수 없습니다. 그리고 문자열 리터럴은 배열 유형입니다 (§6.4.5). – kennytm

관련 문제