포인터는 C의 중간 고비쯤 된다. 이 능선만 잘 넘기면 C언어의 활용도가 한 200프로(?) 향상 되고 이해가 되지
않았던 부분들도 조금씩 풀려나가는 걸 알 수 있었다. 그러나 2차원 배열은 왠지 복잡한 부분이 있다.
포인터배열, 배열포인터, 2차원배열을 포인터로 주소 넘기기 이러한 것들이 나를 혼란스럽게 한다.
책을 읽어보니 이해가 팍팍 되었다. 그럼 책에 내용을 정리해본다.
int imsi[3];
int *imsip;
imsip = imsi;
1차원 배열에서 배열과 포인터를 연결시키기 위한 간단한 대입 이다. 그렇다면 2차원 배열은 어떻게 하는걸까?
순간 **imsip 가 떠올라서 써본다면 "꽝" 이다. **imsip는 *ptr 의 주소값인 &ptr을 받는 변수이지 이차원
배열의 주소값을 받지 못한다.
*imsip2[3]; 과 (*imsip)[3]; 의 차이를 정확히 알고 있어야 함수로 주소값을 넘겨주는 작업을 할 때 고생을 줄일
수 있다. 이 둘의 차이는 과연 무엇일까?
imsi[0][0] |
3 |
imsi[0][1] |
5 |
imsi[1][0] |
12 |
imsi[1][1] |
54 |
imsi[2][0] |
534 |
imsi[2][1] |
923 |
imsip |
|
temp[0] |
|
temp[1] |
|
int imsi[3][2] = { {3,5} , {12,54}, {534,923} };
int (*imsip)[2];
int *temp[2];
imsi[3][2]의 정의에 의해서 메모리는 24바이트가 1차원적으로 할당된다.
(*imsip)[2]에 의하여 변수가 하나 할당된다. 이 변수의 이름은 imsip가 되고 2차원배열을 가리킬 수 있는
2차원 배열포인터 변수이다.
*temp[2]는 포인터 변수가 두 개가 생성되고 메모리에도 당연히 두 변수에 대한 할당이 이루어 진다. 주소를
저장할 수 있는 공간이 두 개 생성 된다는 것이다.
쉽게 이야기하면 temp라는 것은 포인터를 저장 할 수 있는 영역이 두개 있는 것이다. 포인터변수가 2개 생기는 게
키포인트!! 이 정도면 포인터배열과 배열포인터의 차이를 어느 정도 이해할 듯 싶다. 특히 이것와 같이 꼭 알아야
할 것이 있는데 배열이 가리키는 주소의 범위이다. 이걸 모르고서는 포인터를 안다고 하면 안될 것이다.
imsip = imsi; 2차원배열포인터에 2차원배열의 주소를 대입 하고 있다.
imsip = &imsi[0][0]; 2차원배열포인터에 1차원배열의 주소를 대입하고 있다.
temp[0] = imsi; 포인터변수에 2차원배열의 주소를 대입하고 있다.
temp[0] = imsi[0]; 포인터변수에 1차원배열의 주소를 대입하고 있다.
2, 3번째는 틀린 문법이다. 위에 설명한 것과 같이 배열이 가리키는 주소의 범위에 따라서 포인터에 대입하느냐
못하는냐가 결정 된다는 것을 꼭 명심하자!