정보처리기사

[정보처리기사 실기] 포인터 배열

@leem 2025. 4. 14. 19:47

1. 포인터 기본 개념

표현 의미 예시 해석
int *p 정수형 포인터 변수 int *p = &a; a의 주소를 저장하는 변수
&변수 변수의 주소값 &a[0] → 100  
*포인터 해당 주소에 있는 *p → 주소 p가 가리키는 곳의 값  

2. 배열과 포인터 관계

int a[3] = {10, 20, 30}; 
int *p = a; // == &a[0]
표현 해석
p[0] or *p a[0] → 10
p[1] or *(p + 1) a[1] → 20
p[2] or *(p + 2) a[2] → 30
  • p는 배열의 첫 번째 요소를 가리키고 있으므로, p[0] 또는 *p는 a[0]과 동일
  • p[1] 또는 *(p + 1)은 a[1]과 동일하고, p[2]는 a[2]를 가리

 

📌 즉, 배열처럼 쓰면 된다. 주소 계산은 자동으로 처리됨!

 


3. 주소값과 값 구분

  • p는 포인터가 가리키는 주소값을, *p는 해당 주소에 저장된 값을 참조
  • p + 1은 주소를 1 증가시킨 것을 의미하고, *(p + 1)은 그 주소에 저장된 값을 가져옴
표현 예시
p 주소값 p = 103
*p 그 주소의 *p = -10
p + 1 다음 주소 주소가 1 증가
*(p + 1) 다음 주소에 있는 값 예: *(104)

예제에서는 주소값이 100부터 시작해 1씩 증가한다고 가정

 

예제 1 – 1차원 배열과 포인터

int a[3] = {-3, 14, 5};
int *p = &a[1];

printf("%d, ", a[1]);     
printf("%d, ", p[1]);

🔍 풀이

주소
100 -3
101 14
102 5
  • a[1] = 14 이므로 p = &a[1]이면 p는 a[1]의 주소인 101번지를 가리킴.
  • p = &a[1] = 101
    a[1] 배열의 두 번째 요소 (14)
    &a[1] a[1]의 주소값 (101번지)
    p 주소값을 저장하는 포인터 변수
    *p p가 가리키는 주소의 → 14
  • p[1] = *(p + 1) = *(102) = 5
    • p는 &a[1], 즉 배열 a의 두 번째 요소(14)의 주소인 101번지를 저장함
    • 포인터 p를 기준으로 보면 p[0] = *p = *(101) = 14
    • 그러면 p[1]은 *(p + 1) = *(101 + 1) = *(102) → 값 5
    • p가 배열의 중간(a[1])부터 시작하는 새 배열처럼 동작하는 것

✅ 출력 결과: 14, 5


예제 2 – 2차원 배열을 1차원처럼

int a[2][3] = {{-3,14,5}, {1,-10,8}};
int *p = a[1];

printf("%d,", a[1][1]);
printf("%d,", p[1]);

🔍 풀이

주소 설명
100 -3 a[0][0]
101 14 a[0][1]
102 5 a[0][2]
103 1 a[1][0]
104 -10 a[1][1]
105 8 a[1][2]
  • a[1]은 2차원 배열에서 두 번째 행: {1, -10, 8}
  • int *p = a[1]; → p는 a[1][0]의 주소103번지를 저장
  • 즉, p는 배열 {1, -10, 8}의 첫 요소를 가리키는 포인터가 된 것!

📌 그럼 각 요소는?

표현 의미
p[0] *(p + 0) = *(103) 1
p[1] *(p + 1) = *(104) -10
p[2] *(p + 2) = *(105) 8

p는 a[1]의 시작 주소를 가리키기 때문에, p[1]은 a[1][1]과 같은 위치인 104번지의 값을 의미하며 그 결과는 -10이다.

  • a[1][1] = -10
  • p = a[1] = &a[1][0] = 103
  • p[1] = *(p + 1) = *(104) = -10

✅ 출력 결과: -10, -10


예제 3 – 포인터 배열과 이동

int a[2][3] = {{-3,14,5}, {1,-10,8}};
int *b[] = {a[0], a[1]};
int *p = b[1];

printf("%d, ", *b[1]);        
printf("%d, ", *(++p));       
printf("%d", *(--p - 2));

🔍 풀이 

주소 설명
100 -3 a[0][0]
101 14 a[0][1]
102 5 a[0][2]
103 1 a[1][0]
104 -10 a[1][1]
105 8 a[1][2]
  • int *b[] = {a[0], a[1]};
    b는 포인터 배열: 각각의 요소가 주소(포인터) 를 담고 있음 ✨값이 들어간 게 아님!
    b[0] = a[0] 첫 번째 행 시작 주소 100번지
    b[1] = a[1] 두 번째 행 시작 주소 103번지
    → 즉, b[1]은 배열 a[1]을 가리킴
  • int *p = b[1];
    → p는 a[1][0] = 1의 주소인 103번지
  • *b[1]  ✨ *이 붙으면 그 주소에 저장된 "값"을 꺼냄 (103번지에 저장된 값)
    → *103 = a[1][0] = 1
  • *(++p)
    → ++p는 p를 103번지에서 104번지로 이동 → a[1][1]
    → *p = *104 = -10
  • *(--p - 2)
    → --p로 p를 한 칸 되돌려서 다시 103번지
    → p - 2 = 101번지
    → *101 = a[0][1] = 14
  1. *b[1] = *103 = 1
  2. ++p → p = 104 → *(p) = -10
  3. --p → p = 103, p - 2 = 101 → *(101) = 14

✅ 출력 결과: 1, -10, 14


마무리

  • 포인터는 배열처럼 생각하면 된다.
  • *p, p[n], *(p + n) → 전부 같은 의미
  • 주소 이동을 상상하면 추적이 쉬워진다