C 기본 문법 – 포인터 – 1 – 포인터와 배열

C 기본 문법 – 포인터 – 1편: 포인터와 배열 완전 정복

안녕하세요, 여러분! 😊
이번 시간에는 C 언어에서 아주 자주 쓰이고 중요한 개념인 포인터와 배열의 관계를 알아볼 거예요.

🧠 포인터와 배열은 무슨 관계일까요?
포인터는 “주소”를 저장하는 변수이고,
배열은 “같은 자료형의 값들이 연속적으로 저장된 공간”이죠.
그런데 놀랍게도 배열의 이름은 포인터처럼 동작한다는 사실!
마치 아파트 단지의 첫 호실 주소를 담은 메모처럼요.
배열의 이름 자체가 첫 번째 요소의 주소를 의미한답니다!

그럼 이 두 개념이 어떻게 연결되어 있는지, 예제와 함께 자세히 살펴볼게요!


1. 배열 이름은 포인터다?

C 언어에서는 배열 이름 자체가 해당 배열의 첫 번째 요소의 주소를 의미합니다.

int arr[5] = {10, 20, 30, 40, 50};

printf("%p
", arr);    // arr[0]의 주소
printf("%p
", &arr[0]); // arr[0]의 주소 (같음)

🎯 arr&arr[0]은 같은 주소를 가리켜요!


2. 배열 요소에 포인터로 접근하기

배열의 요소에 []뿐 아니라, * 연산자와 포인터 연산을 통해 접근할 수 있습니다.

int arr[3] = {100, 200, 300};

printf("%d
", *arr);        // arr[0]
printf("%d
", *(arr + 1));  // arr[1]
printf("%d
", *(arr + 2));  // arr[2]

💡 arr[i] 는 사실 *(arr + i) 와 동일한 표현입니다!


3. 배열을 가리키는 포인터 선언

int arr[3] = {1, 2, 3};
int *p = arr;

printf("%d
", p[0]); // 1
printf("%d
", p[1]); // 2

🎯 parr과 똑같이 동작해요. 배열처럼 인덱스로 접근 가능합니다!


4. 포인터로 배열 전체 탐색하기

int nums[5] = {11, 22, 33, 44, 55};
int *ptr = nums;

for (int i = 0; i < 5; i++) {
    printf("nums[%d] = %d
", i, *(ptr + i));
}

📌 포인터 연산으로 배열을 순회할 수 있어요!


5. 배열을 함수에 포인터로 전달하기

C에서는 배열을 함수 인자로 넘길 때 자동으로 포인터로 변환됩니다.

예시

void printArray(int *arr, int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", *(arr + i));
    }
    printf("
");
}

int main() {
    int nums[4] = {7, 14, 21, 28};
    printArray(nums, 4);  // nums는 배열이지만 포인터처럼 전달됨
    return 0;
}

6. 다차원 배열과 포인터

int matrix[2][3] = {
    {1, 2, 3},
    {4, 5, 6}
};

2차원 배열은 다음처럼 포인터 배열처럼도 쓸 수 있어요:

printf("%d
", *(*(matrix + 1) + 2));  // matrix[1][2] == 6

🎯 matrixint (*)[3] 타입이고, matrix + 1은 다음 행을 가리켜요!


7. 배열과 포인터의 차이점

항목 배열 포인터
선언 방식 int arr[3]; int *p;
메모리 크기 정해진 크기 할당 변수처럼 주소 저장
주소 변경 불가능 가능
크기 계산 sizeof(arr)는 전체 크기 sizeof(p)는 포인터 크기(4 또는 8바이트)

예시

int arr[3] = {1, 2, 3};
int *p = arr;

printf("%lu
", sizeof(arr)); // 12 (3개 × 4바이트)
printf("%lu
", sizeof(p));   // 8 (64bit 시스템에서 포인터 크기)

8. 포인터를 이용한 배열 요소 변경

void setZero(int *arr, int size) {
    for (int i = 0; i < size; i++) {
        *(arr + i) = 0;
    }
}

int main() {
    int nums[3] = {5, 10, 15};
    setZero(nums, 3);

    for (int i = 0; i < 3; i++)
        printf("%d ", nums[i]);  // 모두 0 출력
}

💡 배열을 포인터로 넘기면 함수 안에서 직접 값을 변경할 수 있어요!


✅ 포인터와 배열 요약 정리

표현 의미
arr 배열의 시작 주소
&arr[0] 첫 요소 주소
*arr 첫 요소의 값
*(arr + i) i번째 요소의 값
arr[i] 배열 요소 접근의 축약 표현

⚠️ 포인터와 배열 사용 시 주의사항

주의사항 설명
배열 크기 포인터로는 배열 크기를 알 수 없음 (sizeof 다름)
잘못된 인덱스 범위를 벗어나면 오류 또는 예기치 않은 동작 발생
포인터 연산 포인터 산술은 해당 자료형 단위로 증가
함수 인자 전달 시 배열은 포인터로 변환되어 값 복사가 아님

마무리하며 💬

포인터와 배열은 C 언어에서 뗄래야 뗄 수 없는 관계예요!
처음에는 헷갈릴 수 있지만, 배열의 이름이 포인터처럼 동작한다는 점만 기억하시면
문제를 푸는 데 훨씬 더 유연한 사고를 하실 수 있어요.

🎯 배열은 값의 묶음이고,
포인터는 그 묶음의 입구 주소표지판이라 보면 됩니다! 🏷️

다음 시간에는 문자열과 포인터에 대해 배워볼게요!
궁금한 점이나 더 보고 싶은 예제가 있다면 언제든지 말씀해주세요!

늘 함께 공부하는 챗GPT였습니다 😊📘

답글 남기기