2014-09-24 2 views
0

처음에는 실수로 발견되었지만 C의이 기능은 매우 흥미 롭습니다. 다음과 같은 간단한 프로그램 :'0 [배열]'은 C에서 잘 작동

#include <stdio.h> 
#include <string.h> 

main() 
{ 
    int array[5]; 
    array[0] = 1; 
    printf("%d",0[array]); 
} 

은 C에서 컴파일 오류없이 작동하며 예상 한 것이 아닙니다. 그리고 출력물에 1을 인쇄합니다. 그래서 난 그냥 주위 궁금이 놀라운 발견하고이 코드도 C에서 잘 작동 발견하고이 출력에 10을 인쇄합니다 :

#include <stdio.h> 
#include <string.h> 

main() 
{ 
    int array[5]; 
    array[0] = 1; 
    array[1] = 10; 
    printf("%d",0[array+1]); 
} 

나는이 두 가지 더 컴파일 오류가없는 이유를 알고 싶어하고 또한 내가 원하는 두 번째 작품이 어떻게 작동하는지 알고 싶습니다. 또한이 기능의 흥미로운 사용법을 높이 평가할 것입니다.

+0

C 배열에서 실제로 존재하지 않는다는 사실이 또 다른 표현입니다. –

+0

@ 뜨거운 핥기 :별로. 배열은 B 언어로 "실제로 존재하지 않았습니다". C 배열은 다르지만 인터페이스 사양이 B와 의도적으로 호환되므로 C 배열에서 "실제로 존재하지 않습니다"라는 표시가있을 수 있습니다. 이것은 환상이다. 배열은 C 안에 존재합니다. – AnT

+0

@HotLicks 그게 무슨 뜻입니까? 나는 C 프로그래머가 아니므로, 당신이 말한 것에 대해 많이 알지 못했습니다. 더 잘 이해할 수있는 링크를 제게 제공 할 수 있습니까? – Lrrr

답변

3

표준에 따라 사용자가 관찰하는 동작은 :

6.5.2.1 대괄호 []에 표현 하였다

후위 식 첨자 배열은의 첨자 명칭이며 배열 객체의 요소. 첨자 연산자 [] 의 정의는 E1 [E2](* ((E1) + (E2)))과 동일합니다.

그래서, 당신의 예에서 0[array](*(0 + array))이되고, 0[array+1](*(0 + array + 1))된다. 이 값은 각각 유효한 진술 인 *array*(array+1)으로 줄일 수 있습니다.

1

대괄호 배열 구문은 순차적으로 할당 된 메모리 블록에 대한 메모리 포인터를 처리하는 사용하기 쉬운 방법입니다.

당신이 발견 한 것은 C에서 포인터 연산이 작동하는 방식의 결과물입니다. 모든 변수는 메모리의 특정 주소에 저장되고 배열은 메모리의 행에있는 여러 변수입니다 (코드가 우려). 따라서 배열의 이름은 메모리의 첫 번째 항목에 대한 포인터이고 인덱스는 오프셋입니다. 컴파일러는이를 함께 추가하여 최종 주소를 얻습니다. 따라서 어떤 순서로 나열하는지는 중요하지 않습니다. C에서

, 다음 줄의 코드를 출력 똑같은 세번 :

int values[] = {0, 1, 2}; 
printf("%d %d %d", values[1], 1[values], *(values + 1)); 

세 번째 메모리 주소에 액세스하는 수동 방법이다. 먼저 배열의 첫 번째 바이트에 대한 포인터로 시작하여 인덱스에 대한 오프셋을 추가합니다.

+0

'values'는 포인터 객체이므로'+ 1'은 암시 적으로 4 바이트를 포인터에 추가하지 않습니까? (확실하지 않지만 어딘가에서 배우는 것을 기억합니다). – Jon

+0

당신은 모두 정확합니다. 나는 그것을 고쳤다. –

+0

@Jon은 * int *에 대한 포인터이기 때문에 sizeof (int) 바이트를 추가합니다 (많은 시스템에서는 4이지만 항상 그런 것은 아닙니다). – RastaJedi