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
🎯
p
는arr
과 똑같이 동작해요. 배열처럼 인덱스로 접근 가능합니다!
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
🎯
matrix
는int (*)[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였습니다 😊📘