2017-03-20 8 views
4

다음은 gcc 버전 6.3에 의해 유효 c 코드로 받아 들여진다 이것에 대한 합리적인 이유가있는 것은 사실이지만 그것이 무엇인지 궁금합니다. 이 질문은 바이트 배열 (따라서 이 아닌 char이 아닌)을 초기화해야 할 때의 동기로, "\x43\xde\xa0"이 아닌 { '\x43', '\xde', '\xa0' }과 같은 것을 작성하고 *my_array 대신 my_array[]을 쓰는 것을 잊으면 곧 컴파일러에 잡히다. 당신이 믿는대로 green의 이니셜 문자의 배열이 아니기 때문에C char 배열 V의 C의 문자는 * 초기화

+5

'white'의 정의는 문자열 끝에 null 종결자가 ('\ 0') 없기 때문에 다른 두 문자와 동일하지 않습니다. – abelenky

+0

@abelenky 오 예, 이것은 제가 간과 한 좋은 지적입니다, 감사합니다. –

+0

'char * green = { "a", "b", "c"};'....;) – LPs

답변

7

다음은 오류를

char *green = { 'a', 'b', 'c' }; 

를 생성합니다. 그것은 타입이 없으며, 그냥 중괄호로 묶은 초기화리스트입니다. 이전 샘플 (즉, white)에서 초기화되는 것은 해석 방법을 결정합니다. 동일한 초기자를 사용하여 3자를 보유 할 수있는 집계를 초기화 할 수 있습니다.

그러나 은 포인터가 아니며 집계가 아니므로 중괄호로 묶은 이니셜 라이저 목록을 초기 값으로 사용할 수 없습니다.

char blue[] = "abc"; 
char *red = "abc"; 

blue 배열이다 두 작업하면서도 다른 의미로 다음 이제 1

. 리터럴 "abc"과 동일한 내용을 유지합니다. red이고 점은 "abc"입니다.


  1. 당신은 compound literal expression 사용할 수 있습니다

    char *green = (char[]){ 'a', 'b', 'c' }; 
    

    그것은 익명의 객체를 생성하는 컴파일러를 알려줍니다 (선언의 범위에 의존하는의 수명을), 즉이다 문자 배열 유형이며 세 문자로 초기화됩니다. 그런 다음 포인터에 해당 개체의 주소가 할당됩니다.

+0

모두 매우 사실입니다. 그러나 이니셜 라이저 목록을'char' 배열 리터럴 (문자열 리터럴과 반대)으로 바꾸고'char * '선언의 의미를 논의함으로써'char *'선언을 수정할 수있는 방법이 있다면 대답은 훨씬 더 좋을 것입니다. 그렇게. –

+0

@JohnBollinger - 복합 리터럴에 대한 정보를 입력하고 있습니다. – StoryTeller

+0

@StoryTeller 도움을 주셔서 대단히 감사합니다. –

5

이 세 가지 선언

char white[] = { 'a', 'b', 'c' }; 
char blue[] = "abc"; 
char *red = "abc"; 

는 다르다.

첫 번째 문자는 이니셜 라이저 수에 해당하는 정확히 3자를 포함하는 문자 배열을 선언합니다.

두 번째 문자 배열은 문자 0을 포함하여 4 개의 문자가있는 문자열 리터럴로 초기화되므로 4 문자의 문자 배열을 선언합니다. 따라서이 문자 배열에는 문자열이 들어 있습니다.

세 번째 문자 배열은 문자 배열 인 문자열 리터럴을 정의하고 문자열 리터럴에 해당하는 문자 배열의 첫 번째 문자 주소로 초기화되는 char * 유형의 포인터를 선언합니다. 왼쪽 객체가 스칼라 하나 이상의 초기화를 포함하는 목록에 의해 초기화되지 않을 수 있기 때문에

당신은

char unnamed = { 'a', 'b', 'c', '\0' }; 
char *red = unnamed; 

처럼

char *green = { 'a', 'b', 'c' }; 

가 잘못이 선언이 선언을 상상할 수있다.

복합 문자를 사용하여 포인터를 초기화 할 수 있다는 점을 고려하십시오. 예를 들어,

char *green = (char[]){ 'a', 'b', 'c' }; 
+0

고마워요. –

+0

@SvenWilliamson 아니요. 천만에요. –