다른 대답은 정확하지만 그중 어느 것도 세 가지 모두가 같은 가치를 포함 할 수 없다는 생각을 강조하지 않으므로 어떤 방식 으로든 불완전합니다.
이것이 다른 답변에서 이해할 수없는 이유는 대부분의 상황에서 도움이되고 확실히 합리적이지만 모든 그림이 포인터 x
자체를 가리키는 상황을 다루지 않기 때문 입니다.
이것은 구성하기가 쉽지만 이해하기가 다소 어렵습니다. 아래 프로그램에서 세 값을 모두 동일하게 만드는 방법을 살펴 보겠습니다.
참고 : 이 프로그램의 동작은 정의되지 않습니다,하지만 난 포인터가 무언가 흥미로운 데모로 순수 여기를 게시하도록하겠습니다 수 없지만, 안 .
#include <stdio.h>
int main () {
int *(*x)[5];
x = (int *(*)[5]) &x;
printf("%p\n", x[0]);
printf("%p\n", x[0][0]);
printf("%p\n", x[0][0][0]);
}
C89 및 C99에서 경고없이 컴파일되며 출력은 다음과 같습니다.
$ ./ptrs
0xbfd9198c
0xbfd9198c
0xbfd9198c
흥미롭게도 세 값은 모두 동일합니다. 그러나 이것은 놀라운 일이 아닙니다! 먼저 프로그램을 분석해 봅시다.
x
각 요소가 int에 대한 포인터 유형 인 5 개의 요소 배열에 대한 포인터로 선언 합니다. 이 선언은 런타임 스택에 4 바이트를 할당하거나 구현에 따라 4 바이트를 할당하므로 내 컴퓨터 포인터는 4 바이트이므로 x
실제 메모리 위치를 나타냅니다. C 언어 군에서, 그 내용 x
은 단지 쓰레기 일 뿐이며, 이전에 사용했던 장소에서 남은 것이므로, 그 x
자체는 어느 곳도 가리 키지 않습니다. 분명히 할당 된 공간이 아닙니다.
따라서 자연스럽게 변수의 주소를 x
가져다가 어딘가에 놓을 수 있습니다. 이것이 바로 우리가하는 일입니다. 그러나 계속해서 x 자체에 넣겠습니다. &x
와 유형이 다르기 때문에 x
캐스트를해야 경고가 표시되지 않습니다.
메모리 모델은 다음과 같습니다.
0xbfd9198c
+------------+
| 0xbfd9198c |
+------------+
따라서 주소의 4 바이트 메모리 블록 0xbfd9198c
에는 16 진수 값에 해당하는 비트 패턴이 포함 0xbfd9198c
됩니다. 충분히 간단합니다.
다음으로 세 가지 값을 인쇄합니다. 다른 답변은 각 표현이 무엇을 의미하는지 설명하므로 관계가 명확해야합니다.
값이 동일하지만 매우 낮은 수준에서만 비트 패턴이 동일하지만 각 식과 관련된 형식 데이터는 해석 된 값이 다르다는 것을 알 수 있습니다. 예를 들어, x[0][0][0]
format string을 사용하여 인쇄 %d
하면 큰 음수를 얻게되므로 실제로 "값"은 달라 지지만 비트 패턴은 동일합니다.
다이어그램에서 화살표는 다른 메모리 주소가 아닌 동일한 메모리 주소를 가리 킵니다. 그러나 정의되지 않은 동작으로 인해 예상되는 결과를 도출 할 수 있었지만 정의되지 않은 것입니다. 이것은 프로덕션 코드가 아니라 완벽을 기하기위한 데모입니다.
합리적인 상황에서 malloc
5 int 포인터의 배열을 만들고 해당 배열에서 가리키는 int를 다시 만드는 데 사용합니다. malloc
항상 고유 한 주소를 반환합니다 (메모리가 없으면 NULL 또는 0을 반환하지 않는 한). 이와 같은 자기 참조 포인터에 대해 걱정할 필요가 없습니다.
바라건대 그것은 당신이 찾고있는 완전한 대답입니다. 당신은 기대하지 말아야 x[0]
, x[0][0]
그리고 x[0][0][0]
동일하게하지만, 강제로 한 경우에는이 될 수 있습니다. 머릿속에 무언가가 있으면 알려주세요.
x[0]
,x[0][0]
및x[0][0][0]
다른 유형이있다. 비교할 수 없습니다. 무슨 소리 야!=
?