2014-07-20 3 views
0

이 예를 살펴 :정수 배열에 대한 포인터가 C에서 어떻게 작동합니까?

#include <stdio.h> 
#include <stdlib.h> 

int main() { 
    int a[5] = {1,2,3,4,5}; // LINE A 
    int (*b)[5] = &a;   // LINE B 
    printf("%d\n", (*b)[0]); // LINE C 
} 
  1. 나는 LINE Bint (*b)[5] = a를 작성 시도했지만 작동하지 않았다. 아무도 왜 이것이 작동하지 않는지 설명 할 수 있습니까? 배열은 포인터로 붕괴되었지만, 왜 내가 명시 적으로 a 주소를 가져 가야하는지 이해할 수 없다. &a. 그것은 부패 되었기 때문에 a은 이미 포인터입니다. 그러나 이제는 포인터의 주소를 취합니까? 더블 포인터? 응?

  2. 아무도 어떻게 (*b)[0]이 작동하는지 설명 할 수 있습니까? 그것은 그 자체가 5 int의 배열에 대한 포인터 인 b을 역 참조하는 것과 같습니다. 그러나 어떻게 든 그것의 원소를 취합니다. 이 경우 [0] 번째 요소가 5 개의 정수가 아닌가? 나는 어떻게 든 하나의 정수로 끝나고 1을 출력한다.

저는 정말 혼란 스럽습니다. 감사.

+1

1) 배열은 자체 요소에 대한 포인터가 아니라 첫 번째 요소에 대한 포인터로 감소합니다.2) "5 ints의 배열에 대한 포인터"를 역 참조하는 경우, "5 개의 정수 배열"을 얻습니다. 그러면 '[0]'으로 색인화됩니다. –

+0

배열은'sizeof','_Alignof' (C11),'&'(귀하의 경우에 적용됨) 또는 배열 초기화 프로그램에서 사용 된 문자열 리터럴의 피연산자가 아닌 경우에만 감소합니다. – mafso

+0

@mafso 이것은 '_Alignof'에'_Alignof'에 적용되지 않습니다. 피연산자는 유형 이름이며 표현식이 될 수 없습니다. c11의 초안 버전은 버그가 있으며 c11의 릴리스 버전에서 수정되었습니다. – ouah

답변

2
int a[5]={1,2,3,4,5}; 

-------In Memory---------- 
| 1 || 2 || 3 || 4 || 5 | 
---------------------------           
101 105 109 113 117 //Assume these are addresses 

기본적으로 배열 이름은 첫 번째 요소에 대한 포인터처럼 작동합니다. 첫 번째 요소 포인터 등 그래서 a 작용

너무 aint *a으로 소멸된다 (여기 소자 정수이다); 그것은 다음과 같이 계산합니다 아래와 같이 당신이, 그때는 요소의 다음 주소로 이동합니다 하나 증가하면 왜 그게 전부 : 1 요소 + (n 개 *의를 sizeof (int)를)

(a+0)--->101 // 101 + 0*sizeof(int) 
(a+1)--->105 // 101 + 1*sizeof(int) 
(a+2)--->109 // 101 + 2*sizeof(int) 
(a+3)--->113 // 101 + 3*sizeof(int) 
(a+4)--->117 // 101 + 4*sizeof(int) 

주소 그러나 포인터와 같은 &a 행위는 당신이 하나를 추가 할 때, 즉, 다음은

(&a+1)----->121 //101 + 1*sizeof(a) 

아래와 같이 향후 5 integers.As를 가리 키도록 노력할 것입니다 을 의미한다 (5 개의 int이 경우 포인터에) 배열을 완료 그게 왜이 줄에 int (*b)[5] = &a; 아무런 문제가 없습니다.하지만 시도 할 때 int(*b)[5]=a; a은 (* b) [5]가 5 개의 정수에 대한 포인터 인 단일 정수에 대한 포인터이므로 호환되지 않습니다. 호환되지 않는 포인터 유형을 할당 할 수 없습니다.

-4

- int a [5]를 선언하면 컴파일러에서 'a'를 내부 메모리에 대한 참조로 사용하고 있습니다. 'a'자체는 변수가 아닙니다. 따라서 &가 작동하지 않습니다.

+1

'a'는 매우 많은 변수입니다. –

0

b은 배열 a에 대한 포인터입니다. 역 참조 b은 전체 배열 a을 제공합니다. 따라서 표현식에 *b을 사용하면 해당 역 참조 된 배열의 이름을 나타냅니다. 배열 이름은 배열의 첫 번째 요소에 대한 포인터로 변환되므로 *ba (또는 *b)의 첫 번째 요소를 가리키는 포인터로 붕괴합니다. *b은 부패 후 유형이 int *입니다. 따라서 (*b)[i]번째b이 가리키는 배열 요소를 제공합니다.

+0

이 작업을 수행하기 위해 포인터로 쇠퇴 할 필요가 없습니다. 배열 인덱싱없이 작동합니다. –

+1

@MarkRansom : 표준과 관련하여 배열이 완전히 훼손되지 않도록 배열은이 시나리오에서 부패했습니다 (C99, 6.3.2.1 p3 참조). –

관련 문제