cheoly's language study blog

포인터와 배열의 관계: C언어 초보자를 위한 이해와 활용

프로그래밍/C언어
반응형
SMALL

포인터와 배열은 매우 긴밀한 관계를 맺고 있으며, 어떤 부분에서는 서로를 대체할 수도 있습니다. 배열의 이름은 그 값을 변경할 수 없는 상수라는 점을 제외하면 포인터와 같습니다. 따라서 배열의 이름은 포인터 상수 (constant pointer)입니다.

간단히 설명하자면 둘다 비슷한 속성을 가지고 있지만 배열은 메모리공간을 사용자 마음대로 접근하며 데이터를 넣고 수정할 수 있다. 포인터 같은 경우에는 특정 메모리에 주소값을 가지고 있어서 간접참조를 하는 방식이다.

포인터와 배열의 차이점


배열은 변수 선언과 함께 자신의 데이터를 저장할 공간을 배열의 크기만큼 연속적인 공간을 가집니다. 포인터는 자신이 데이터를 저장할 공간을 가지지 않고 저장할 공간이 있는 위치를 저장하는 메모리 번지를 저장합니다.

배열은 그 자체가 크기 때문에 함수의 인수로 전달할 수 없지만 포인터는 대상체가 무엇이든간에 4바이트의 크기밖에 차지하지 않으므로 함수로 전달할 수 있습니다. 그래서 배열을 함수로 전달할 때는 반드시 포인터를 사용해야 합니다.

포인터와 배열의 사용 이유


일반적으로 포인터를 사용하는 목적은 동적으로 메모리를 할당하여 사용하기 위해서 사용합니다. 그리고 메모리가 할당된 후에는 배열처럼 사용하면 된다고 이전에 설명하였습니다.

배열은 변수들을 메모리상에 일렬로 나열해놓은 것과 마찬가지입니다. 배열도 메모리상에 존재하므로 엄연히 주소값이 존재합니다. 배열 포인터란 이 주소값을 가리키는 포인터를 말합니다. 이것이 유용한 이유는 바로 2차원 이상의 배열을 가리킬 때 포인터를 통해 배열과 같은 인덱싱을 할 수 있기 때문입니다. 함수에 2차원 이상의 배열을 파라미터로 던질 때 유용하게 사용됩니다.

배열과 포인터의 관계


배열의 이름은 그 값을 변경할 수 없는 상수라는 점을 제외하면 포인터와 같습니다. 따라서 배열의 이름은 포인터 상수 (constant pointer)입니다.

배열 포인터는 배열의 주소값을 저장하고 인덱싱할 수 있는 포인터를 말합니다. 배열 이름은 1차원 배열에서는 포인터와 같지만, 2차원 이상의 배열에서는 포인터의 역할을 하지 않습니다.

예제


#include <stdio.h>

int main(void) {
    int arr[3] = {1, 2, 3};
    int *ptr = arr; // 배열의 이름은 포인터 상수이므로 포인터 변수에 할당 가능

    printf("arr[0]: %d\n", arr[0]);
    printf("ptr[0]: %d\n", ptr[0]);
    printf("*ptr: %d\n", *ptr);

    ptr[0] = 4; // 포인터 변수를 이용해 배열의 값을 변경 가능
    printf("arr[0]: %d\n", arr[0]);

    return 0;
}

위의 예제에서 `arr`은 배열이고 `ptr`은 포인터 변수입니다. `arr`는 배열의 이름이므로 포인터 상수이기 때문에 `ptr`에 할당할 수 있습니다. 그리고 `ptr`을 이용해 배열의 값을 변경할 수 있습니다.

반응형
LIST