목차
- 배열
- 포인터
- 배열과 포인터
- 2차원 배열과 포인터
배열은 값을 연속해서 저장하는 공간이고,
포인터는 그 공간의 주소를 저장하는 변수다.
1. 배열
배열은 같은 자료형의 값을 여러 개, 순서대로 저장하는 공간
int arr[3] = {10, 20, 30};

2. 포인터
포인터는 주소를 저장하는 변수
int num = 10;
int *p = #

포인터를 통해 실제 값을 바꿀 수도 있다.
*p = 50;
그러면 p가 가리키는 곳의 값이 바뀌므로,
printf("%d", num); // 50
3. 배열과 포인터의 관계
int arr[3] = {10, 20, 30};
int *p = arr;
p
│
▼
주소 200 204 208
┌────────┬────────┬────────┐
배열 arr │ arr[0] │ arr[1] │ arr[2] │
├────────┼────────┼────────┤
저장된 값 │ 10 │ 20 │ 30 │
└────────┴────────┴────────┘
p = arr; 이므로, p는 배열의 첫 번째 원소 arr[0]의 주소를 저장한다.
arr = 200 // 첫 번째 원소의 주소
&arr[0] = 200 // 첫 번째 원소의 주소
p = 200 // arr[0]을 가리키는 포인터
arr[0] = 10 // 첫 번째 원소의 값
*p = 10 // p가 가리키는 곳의 값
따라서
다음 원소로 이동하기
p ──▶ arr[0] ──▶ 값 10
p + 1 ──▶ arr[1] ──▶ 값 20
p + 2 ──▶ arr[2] ──▶ 값 30
*(p + 0) // 10
*(p + 1) // 20
*(p + 2) // 30
배열 방식으로 쓰면:
arr[0] // 10
arr[1] // 20
arr[2] // 30
따라서
// 배열 == 포인터 표현 == 값
arr[0] == *(arr + 0) == *p
arr[1] == *(arr + 1) == *(p + 1)
arr[2] == *(arr + 2) == *(p + 2)
다음 원소로 이동하기
int arr[3] = {10, 20, 30};
int *p = arr;
p가 1000을 가리킨다고 하고, int가 4바이트라면,
p + 1
은 주소 1001이 아니라 다음 int 원소 위치인 1004를 가리킨다.
p // arr[0]의 주소
p + 1 // arr[1]의 주소
p + 2 // arr[2]의 주소
포인터 연산은 자료형 크기를 고려해서 이동한다.
| 포인터 자료형 | p+1 이 이동하는 크기 |
| char *p | 1바이트 |
| int *p | 보통 4바이트 |
| double *p | 보통 8바이트 |
4. 2차원 배열과 포인터
int arr[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
int가 4바이트라고 가정하고, 주소를 편의상 이렇게 두자.
arr[0][0] : 200 arr[0][1] : 204 arr[0][2] : 208
arr[1][0] : 212 arr[1][1] : 216 arr[1][2] : 220
시각화하면:
arr
│
▼
0행 1행
┌───────────────┬───────────────┐
│ arr[0] │ arr[1] │
│ ┌────┬────┬────┐ │ ┌────┬────┬────┐ │
│ │ 1 │ 2 │ 3 │ │ │ 4 │ 5 │ 6 │ │
│ └────┴────┴────┘ │ └────┴────┴────┘ │
└───────────────┴───────────────┘
200 204 208 212 216 220
arr은 첫 번째 행의 주소
1차원 배열에서는 arr이 첫 번째 원소의 주소처럼 쓰였는데,
2차원 배열에서는 arr이 첫 번째 행의 주소처럼 쓰인다.
arr == &arr[0]
arr[0] == &arr[0][0]
arr[1] == &arr[1][0]
즉,
- arr : 0행 전체를 가리킴
- arr[0] : 0행의 첫 번째 원소를 가리킴
- arr[1] : 1행의 첫 번째 원소를 가리킴
arr + 1은 “다음 행”으로 이동
arr ──▶ arr[0]
arr + 1 ──▶ arr[1]
즉,
arr + 1 == &arr[1]
여기서 주의할 점:
arr + 1은 다음 원소가 아니라, 다음 행으로 이동한다.
왜냐하면 arr의 한 칸은 int[3], 즉 int 3개짜리 한 행이기 때문이다.
그래서 주소도
arr : 200
arr + 1 : 212
처럼 12바이트(= 3 * 4)만큼 이동한다.
arr[i][j]는 포인터로도 표현 가능
2차원 배열에서는 아래 공식이 중요하다.
arr[i][j] == *(*(arr + i) + j)
예를 들어:
arr[0][0] == *(*(arr + 0) + 0) // 1
arr[0][1] == *(*(arr + 0) + 1) // 2
arr[1][2] == *(*(arr + 1) + 2) // 6
연습문제
1.
#include <stdio.h>
int main() {
int arr[] = {10, 20, 30, 40};
int *p = arr;
printf("%d ", *p++);
printf("%d ", *p);
printf("%d", *(p + 1));
return 0;
}
답 : 10 20 30
2.
#include <stdio.h>
void change(int *p) {
*(p + 1) = *p + *(p + 2);
}
int main() {
int arr[] = {2, 4, 6};
change(arr);
printf("%d %d %d", arr[0], arr[1], arr[2]);
return 0;
}
답 : 3 12 9
3.
#include <stdio.h>
void change(int *p) {
*(p + 1) = *p + *(p + 2);
}
int main() {
int arr[] = {2, 4, 6};
change(arr);
printf("%d %d %d", arr[0], arr[1], arr[2]);
return 0;
}
답 : 2 8 6
4.
#include <stdio.h>
int main() {
int arr[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
printf("%d %d %d",
*(*(arr + 0) + 2),
*(*(arr + 1) + 0),
*(*(arr + 1) + 2));
return 0;
}
답 : 3 4 6
5.
#include <stdio.h>
int main() {
int arr[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
int (*p)[3] = arr;
p[0][1] = p[1][0] + p[0][2];
p++;
printf("%d %d %d",
arr[0][1],
(*p)[0],
*(*p + 2));
return 0;
}
답 : 7 4 6
'정보처리기사' 카테고리의 다른 글
| [정처기] 02. C언어 함수, 재귀 +연습 문제 (0) | 2026.06.26 |
|---|---|
| [정처기] 01-1. C언어 변수, 연산자, 출력 형식, 제어문 & 반복문 연습문제 (0) | 2026.06.26 |
| [정처기] 01. C언어 변수, 연산자, 출력 형식, 제어문 & 반복문 (0) | 2026.06.26 |
| 정처기 공부해라 (0) | 2026.06.24 |