작성
·
304
0
강의를 듣다가 2차원 배열은 2중 포인터와 호환이 안된다고 하셨습니다. 저도 2차원 배열은 결국 1차원 배열이니까 당연히 안되겠지 생각해서 이해했습니다.
int arr2[2][2] = { {1,2}, {3,4} };
라는 2차원 배열에서
int* p3 = (int*)arr2;
라는 포인터 변수를 만들고
cout << *p3 << *(p3 + 1) << *(p3 + 2) << *(p3 + 3) << endl;
테스트로 만들어보니 1234가 잘 출력되었습니다.
그런데 강의에서
int(*p2)[2] = arr2;
라는 새로운 타입형 변수를 만들어서 (*p2)[0], p2[0][0] 등등 배열처럼 사용하셨는데
연습 겸 이걸 포인터식으로 사용해보려고
cout << **p2 << *(*p2 + 1) << *(*p2 + 2) << *(*p2 + 3) << endl;
이런 식으로 테스트 해보니 1234 또 잘 나왔습니다.
여기서 **p2는 2중 포인터인데 왜 워프를 두번타는지 이해가 안되었습니다. 그래서 여러가지 테스트를 해보았습니다.
cout << **(p2 + 0) << *(*(p2 + 0) + 1) << **(p2 + 1) << *(*(p2 + 1) + 1) << endl;
이것도 1234가 출력되는데 (p2 + 1)이 왜 8바이트만큼 이동하는지, 다시 말해서 [0][0]에서 [1][0]처럼 이동하는게 이해가 안됩니다. 포인터 연산에서 타입 크기 만큼이동한다고 배웠는데
p2의 타입크기는 int[n][m]에서 (4 * m)바이트 인건가요?
그렇다면 *p2의 타입크기는 int 즉, 4바이트 인건가요?
그리고 p2는 2중포인터 변수인가요?
물론 앞으로 사용하지 않을 것 같지만 궁금증이 문득..
답변 1
0
이 부분을 먼저 이해하셔야 합니다.
경고가 뜨긴 하지만 실행해보면 결과는 똑같이 뜹니다.
int arr[2] = {1,2}를 하면 데이터 {1, 2}이 메모리에 연속해서 할당되고,
첫번째 데이터인 {1}의 메모리 주소가 arr이라는 바구니에 들어가게 됩니다.
---> 편의성 이를 [배열 1 법칙]이라고 가칭을 짓겠습니다.
이를 응용해 int arr2[2][2] = {{1,2},{3,4}}를 하면 다음과 같습니다.
arr2[0][2]가 경고에도 불구하고 3이 뜨는 이유가 뭘까요?
그냥 직접 계산을 해보면 됩니다.
arr2[0] = 200번 주소로 이동하게 되고,
200번 주소로 가면 무엇이 있는데?
~에 대한 해답은 양파까기를 통해 int arr2[2][2]
즉 int 2개짜리 배열이 있다고 주장하고 있습니다.
그런데 [배열 1 법칙]에 의해 사실상 데이터가 바로 있는게 아니라 주소가 있기 때문에
(*'200')[2]는 곧 *((*'200')+2)이라서
해석하면 '200'이라는 주소로 워프를 탄 다음,
데이터 크기만큼 두 칸을 이동해서 그 주소로 이동해! 가 됩니다.
그리고 여기서 데이터 크기는 int의 크기는 4바이트가 됩니다. (int가 있는 배열이라 했기 때문)
뭐 좀 복잡한데 요약하면 위와 같습니다
머릿 속에서 정리가 됩니다! 감사합니다!