33.8 배열을 포인터에 넣기

배열은 사실 첫 번째 요소의 주솟값만 담고 있습니다.

그림 33‑2 배열과 주솟값

즉, 배열은 주솟값이기 때문에 포인터에 넣을 수 있습니다. 따라서 다음과 같이 포인터에 배열을 넣은 뒤 포인터에서 인덱스로 요소에 접근할 수 있습니다.

pointer_to_array.c

#include <stdio.h>

int main()
{
    int numArr[10] = { 11, 22, 33, 44, 55, 66, 77, 88, 99, 110 };    // 크기가 10인 int형 배열

    int *numPtr = numArr;       // 포인터에 int형 배열을 할당

    printf("%d\n", *numPtr);    // 11: 배열의 주소가 들어있는 포인터를 역참조하면 배열의 
                                // 첫 번째 요소에 접근

    printf("%d\n", *numArr);    // 11: 배열 자체를 역참조해도 배열의 첫 번째 요소에 접근

    printf("%d\n", numPtr[5]);  // 66: 배열의 주소가 들어있는 포인터는 인덱스로 접근할 수 있음

    printf("%d\n", sizeof(numArr));    // 40: sizeof로 배열의 크기를 구하면 배열이 메모리에 
                                       // 차지하는 공간이 출력됨

    printf("%d\n", sizeof(numPtr));    // 4 : sizeof로 배열의 주소가 들어있는 포인터의 크기를 
                                       // 구하면 포인터의 크기가 출력됨(64비트라면 8)

    return 0;
}

실행 결과

11
11
66
40
4

int *numPtr = numArr;처럼 배열을 포인터에 바로 할당할 수 있습니다. 단, 자료형이 같아야 하며 1차원 배열이라면 *가 한 개인 단일 포인터라야 합니다.

배열을 포인터에 할당한 뒤 포인터를 역참조해보면 배열의 첫 번째 요소의 값이 나옵니다. 마찬가지로 배열 자체도 역참조해보면 배열의 첫 번째 요소의 값이 나옵니다. 즉, 실제로는 배열도 포인터라 할 수 있습니다.

printf("%d\n", *numPtr);    // 11: 배열의 주소가 들어있는 포인터를 역참조하면 배열의 
                            // 첫 번째 요소에 접근

printf("%d\n", *numArr);    // 11: 배열 자체를 역참조해도 배열의 첫 번째 요소에 접근

배열의 주소가 들어있는 포인터는 인덱스를 통하여 요소에 접근할 수 있습니다.

printf("%d\n", numPtr[5]);    // 66: 배열의 주소가 들어있는 포인터는 인덱스로 접근할 수 있음

배열과 포인터가 다른 점은 sizeof로 크기를 계산했을 때입니다. 배열에 sizeof 연산자를 사용하면 배열이 차지하는 전체 공간이 출력되지만 sizeof로 배열의 주소가 들어있는 포인터의 크기를 구해보면 그냥 포인터의 크기만 나옵니다(32비트라면 4, 64비트라면 8).

printf("%d\n", sizeof(numArr));    // 40: sizeof로 배열의 크기를 구하면 배열이 메모리에 
                                   // 차지하는 공간이 출력됨

printf("%d\n", sizeof(numPtr));    // 4 : sizeof로 배열의 주소가 들어있는 포인터의 크기를 
                                   // 구하면 포인터의 크기가 출력됨(64비트라면 8)