2017-01-06 1 views
-1

sizeof은 대괄호 안에 명시 적으로 지정된 크기없이 선언되었지만 선언에서 초기화되는 배열에서 안전하게 사용할 수 있습니까? 특별한 컴파일러 플래그없이 그 소리-800.0.42.1와 맥 OS에서 컴파일하면이 12의 예상 결과를 산출,명시 적 길이가없는 sizeof 배열

unsigned int arr[] = { 1, 2, 3 }; 
size_t bytes = sizeof arr; 

:

는 다음과 같은 코드를 생각해 보자.
그러나 C 표준 (또는 이에 대해 다른 경우 C 표준)이이를 보장합니까? 아니면 그것이 "제정신"이되도록 unsigned int arr[3]처럼 선언해야합니까?

+2

예. 컴파일러는 크기를 알고 있습니다. –

+0

함수의 헤더가'void somefunction (int arr [], int n);과 같은 함수 내부에있을 때'sizeof (arr)'이 작동하는지 알고 싶습니다. 왜냐하면 호출 루틴에서 'somefunction'에'* int' 타입의 포인터를 넘길 수 있습니다. – ron

+1

@ron - 아니요.'somefunction'이받는 것은 포인터가 아니라 배열입니다. 함수 내에서 sizeof arr은 sizeof (int *)와 같은 결과를 줄 것이다. –

답변

8

예, 표준에서는 크기가 지정되지 않은 경우 배열 요소 개수가 배열 초기화 프로그램의 요소 수와 같음을 보증합니다. C11 standard draft 6.7.9p226.7.9p25를 참조하십시오

알 수없는 크기의 배열이 초기화 될 경우, 그 크기가 명시 적으로 초기화와 가장 큰 인덱스 요소에 의해 결정된다. 유형 배열은 이니셜 라이저 목록의 끝에서 완료됩니다.

예 2 선언

int x[] = { 1, 3, 5 }; 

정의하고 어떤 사이즈가 지정되지 않은 세 초기화 거기되었을 때, 세 개의 요소가 1 차원 배열 대상인 x를 초기화한다.

1

unsigned int arr[] = { 1, 2, 3 }; 실제로 전체 배열을 정의합니다. 배열의 크기는이 컴파일 단위에서 알 수 있으며 n은 sizeof (type)입니다. 여기서 n은 초기화 목록의 요소 수 (여기서는 3)이고 type은 기본 객체 유형 (여기 unsigned int)입니다.

즉, sizeof(arr)arr과 동일한 범위에서 정의되며 예상 값을 갖습니다.


완전히 다를 것은 extern int arr[];입니다. 선언이라는 이름의 배열이 다른 컴파일 단위에서 제공되지만 컴파일러는 크기를 알 수 없습니다. 이 경우 sizeof(arr)을 사용하면 오류가 발생합니다.

단순한 선언의 또 다른 예는 다시 컴파일러는 함수가 그 크기를 알 수 없다 다시 int 배열을받을 수 있지만 것으로 알고 여기

void func(int arr[]) { 
    ... 
} 

입니다. 그러나 여기서 컴파일러는 배열의 주소를받을 포인터를 생성하고 sizeof(arr)이 정의되지만 그 포인터의 크기는 이 아니며 원래 배열의 크기는입니다.

+0

아니요, 세 번째 예에서 컴파일러는 * 알지 못합니다. 함수가 배열을받을 것입니다. 'void func (int arr [])'는'void func (int * arr)'와 정확히 동일합니다. 선언은 컴파일 타임에 "조정"됩니다. 예를 들어'func (NULL)'또는'func (& n)'을 호출하는 것은 매우 합법적입니다.'n'은 배열 요소가 아닌'int' 객체입니다. –