나는 약간의 C ++을 공부하고 있으며 포인터와 싸우고 있습니다. 다음과 같이 선언하면 3 단계의 포인터를 가질 수 있음을 이해합니다.
int *(*x)[5];
그래서 이것은 *x
포인터 인 5 개 요소의 배열에 대한 포인터 int
입니다. 또한 내가 알고 x[0] = *(x+0);
, x[1] = *(x+1)
등등 및 ….
위의 선언에서 왜 그렇 x[0] != x[0][0] != x[0][0][0]
습니까?
답변
x
에 대한 5 개의 포인터 배열에 대한 포인터 int
입니다.
x[0]
에 대한 5 개의 포인터 배열 입니다 int
.
x[0][0]
에 대한 포인터 int
입니다.
x[0][0][0]
입니다 int
.
x[0]
Pointer to array +------+ x[0][0][0]
x -----------------> | | Pointer to int +-------+
0x500 | 0x100| x[0][0]----------------> 0x100 | 10 |
x is a pointer to | | +-------+
an array of 5 +------+
pointers to int | | Pointer to int
0x504 | 0x222| x[0][1]----------------> 0x222
| |
+------+
| | Pointer to int
0x508 | 0x001| x[0][2]----------------> 0x001
| |
+------+
| | Pointer to int
0x50C | 0x123| x[0][3]----------------> 0x123
| |
+------+
| | Pointer to int
0x510 | 0x000| x[0][4]----------------> 0x000
| |
+------+
당신은 그것을 볼 수 있습니다
x[0]
는 배열이며 표현식에서 사용될 때 첫 번째 요소에 대한 포인터로 변환됩니다 (일부 예외 제외). 따라서x[0]
첫 번째 요소의 주소x[0][0]
는0x500
입니다.x[0][0]
의 주소가 포함되어int
있는이0x100
.x[0][0][0]
의int
값을 포함합니다10
.
따라서 x[0]
동일하다 &x[0][0]
그러므로 및, &x[0][0] != x[0][0]
.
따라서 x[0] != x[0][0] != x[0][0][0]
.
답변
x[0] != x[0][0] != x[0][0][0]
자신의 게시물에 따르면
*(x+0) != *(*(x+0)+0) != *(*(*(x+0)+0)+0)`
이것은 단순화
*x != **x != ***x
왜 평등해야합니까?
첫 번째는 포인터의 주소입니다.
두 번째는 다른 포인터의 주소입니다.
그리고 세 번째는 int
가치입니다.
답변
다음은 포인터의 메모리 레이아웃입니다.
+------------------+
x: | address of array |
+------------------+
|
V
+-----------+-----------+-----------+-----------+-----------+
| pointer 0 | pointer 1 | pointer 2 | pointer 3 | pointer 4 |
+-----------+-----------+-----------+-----------+-----------+
|
V
+--------------+
| some integer |
+--------------+
x[0]
“어드레스 주소”,
x[0][0]
“포인터 0”,
x[0][0][0]
“일부 정수”를 나타냅니다.
나는 지금 분명해야한다고 생각한다. 왜 그들은 모두 다르다.
위의 내용은 기본적인 이해를 위해 충분히 가깝기 때문에 내가 쓴 방식으로 썼습니다. 그러나 헥스가 올바르게 지적했듯이 첫 번째 줄은 100 % 정확하지 않습니다. 자세한 내용은 다음과 같습니다.
C 언어의 정의에서 값 x[0]
은 정수 포인터의 전체 배열입니다. 그러나 배열은 C에서 실제로 할 수없는 일입니다. 항상 주소 전체 또는 요소를 조작하고 전체 배열을 전체적으로 사용하지 마십시오.
-
운영자
x[0]
에게 전달할 수 있습니다sizeof
. 그러나 그것은 실제로 값을 사용하는 것이 아니며 결과는 유형에만 달려 있습니다. -
주소를 가져 와서
x
type의 “address of array” 값을 얻을 수 있습니다int*(*)[5]
. 다시 말해:&x[0] <=> &*(x + 0) <=> (x + 0) <=> x
-
에서는 모든 다른 콘텍스트 의 값은
x[0]
상기 어레이의 첫번째 엘리먼트에 대한 포인터로 붕괴된다. 즉, “address of array”값과 유형이있는 포인터입니다int**
. 효과는x
유형의 포인터로 캐스팅 한 것과 같습니다int**
.
경우 3의 배열 포인터 붕괴로 인해, x[0]
궁극적으로 모든 사용은 포인터 배열의 시작을 가리키는 포인터를 생성합니다. 이 호출 printf("%p", x[0])
은 “어드레스 주소”라고 표시된 메모리 셀의 내용을 인쇄합니다.
답변
x[0]
가장 바깥 쪽 포인터 ( int에 대한 포인터의 크기 5의 배열에 대한 포인터) 를 역 참조하고 포인터 의 크기 5의 배열을 만듭니다int
.x[0][0]
최 포인터 역 참조 와 포인터로 결과 인덱스 어레이int
;x[0][0][0]
모든 것을 역 참조하여 구체적인 가치를 창출합니다.
그건 그렇고, 이러한 종류의 선언이 의미하는 것에 혼란 스러우면 cdecl을 사용하십시오 .
답변
단계 식으로 단계를 고려하자 x[0]
, x[0][0]
하고 x[0][0][0]
.
x
다음과 같이 정의됩니다
int *(*x)[5];
expression x[0]
은 유형의 배열입니다 int *[5]
. expression x[0]
은 expression 과 동일 하다는 점을 고려하십시오 *x
. 즉, 배열에 대한 포인터를 참조하여 배열 자체를 얻습니다. 선언처럼 y와 같이 표시하자
int * y[5];
표현식은와 x[0][0]
동일하며 y[0]
유형이 int *
있습니다. 우리가 선언을했다 z와 같이 표시하자
int *z;
expression x[0][0][0]
은 y[0][0]
expression z[0]
과 동등하며 expression 과 동등하며 type을 갖습니다 int
.
그래서 우리는
x[0]
유형이있다 int *[5]
x[0][0]
유형이있다 int *
x[0][0][0]
유형이있다 int
따라서 그것들은 다른 유형의 객체와 다른 크기의 객체입니다.
예를 들어 실행
std::cout << sizeof( x[0] ) << std::endl;
std::cout << sizeof( x[0][0] ) << std::endl;
std::cout << sizeof( x[0][0][0] ) << std::endl;
답변
가장 먼저 말해야 할 것은
x [0] = * (x + 0) = * x;
x [0] [0] = * (* (x + 0) +0) = ** x;
x [0] [0] [0] = * (* (* (x + 0) +0)) = *** x;
따라서 * x ≠ * * x ≠ * * * x
다음 그림에서 모든 것이 명확합니다.
x[0][0][0]= 2000
x[0][0] = 1001
x[0] = 10
x [0] [0] [0] = 10 인 경우의 예일뿐입니다.
그리고 어드레스 X [0] [0] [0] 이다 1,001
해당 주소는 x [0] [0] = 1001에 저장됩니다.
x [0] [0]의 주소 는 2000입니다
그 주소는 x [0] = 2000에 저장됩니다
따라서 x [0] [0] [0] ≠ x [0] [0] ≠ x [0]
.
편집
프로그램 1 :
{
int ***x;
x=(int***)malloc(sizeof(int***));
*x=(int**)malloc(sizeof(int**));
**x=(int*)malloc(sizeof(int*));
***x=10;
printf("%d %d %d %d\n",x,*x,**x,***x);
printf("%d %d %d %d %d",x[0][0][0],x[0][0],x[0],x,&x);
}
산출
142041096 142041112 142041128 10
10 142041128 142041112 142041096 -1076392836
프로그램 2 :
{
int x[1][1][1]={10};
printf("%d %d %d %d \n ",x[0][0][0],x[0][0],x[0],&x);
}
산출
10 -1074058436 -1074058436 -1074058436
답변
실제 관점에서 배열을 볼 경우 다음과 같이 나타납니다.
x[0]
상자로 가득한화물 컨테이너입니다.
x[0][0]
화물 컨테이너 안에 신발 상자로 가득 찬 단일 상자입니다.
x[0][0][0]
상자 안에,화물 컨테이너 안에있는 단일 신발 상자입니다.
화물 컨테이너의 유일한 상자에있는 유일한 신발 상자 였음에도 불구하고 여전히화물 컨테이너가 아닌 신발 상자입니다