간단한 포인터 연습이 나를 머리카락을 뽑게 만들었다

발행: (2026년 1월 31일 오전 06:31 GMT+9)
4 min read
원문: Dev.to

Source: Dev.to

Cover image for How a simple pointer exercise had me pulling my hair out.

나는 주어진 포인터 연습 문제에 대해 (손으로) 출력값을 적어 보라는 과제를 받았다. 겉보기엔 간단해 보였지만, 어느 단계에 이르렀을 때 나는 길을 잃었다. 생각할수록 혼란의 토끼굴에 빠졌고, AI에게 물어봐도 도움이 되지 않았다.

아래는 나를 당황하게 만든 예제, 내가 저지른 실수들, 왜 그것이 틀렸는지, 그리고 이번 경험을 통해 배운 원칙들이다.

Code

int f(int** r, int** s) {
    int temp = r;
    int temp2 = **s;
    int *z = *r;
    *r = *s;
    *s = z;
    printf("r = %d\n", r);
    printf("s = %d\n", **s);
    *z += 3;
    **s -= 8;
    **r -= 19;
    return temp + temp2;
}

int main(void) {
    int a = 80;
    int b = 12;
    int *p = &a;
    int *q = &b;
    int x = f(&p, &q);
    printf("x = %d\n", x);
    printf("*p = %d\n", *p);
    printf("*q = %d\n", *q);
    printf("a = %d\n", a);
    printf("b = %d\n", b);
    return EXIT_SUCCESS;
}

Expected Output

r = 12
s = 80
x = 92
*p = -7
*q = 75
a = 75
b = -7

Mistakes I Made

  1. 잘못된 반환값 – 나는 64를 반환했지만 정답은 92였다.
    5·6번째 줄에서 temptemp2는 각각 r(포인터 값)과 **s(정수 12)의 값을 복사해서 초기화한다. 나는 이후 **r**s에 대한 연산이 temptemp2에 영향을 줄 것이라고 착각했다. 실제로 이 변수들은 독립적인 복사본이며, 값을 바꾸려면 temptemp2 자체를 수정해야 한다(예: temp += 3).

  2. 잘못된 주소를 변경 – 나는 main에서 *p*q가 가리키는 대상을 바꾸었지만, 실제로 바꿔야 할 것은 f 안에서 *r*s가 가리키는 대상이다. 스와핑은 함수에 전달된 포인터 자체에 영향을 주어야 한다.

  3. *z에 대한 오해 – 나는 *z를 주소로 생각하고 *z += 3이 “포인터를 세 칸 이동한다”는 의미라고 여겼다. 실제로 *zint(즉, z가 가리키는 값)이며, *z += 3은 그 정수에 3을 더하는 연산이다. 주소가 바뀌는 것이 아니다.

이러한 오해 때문에 나는 계속해서 원을 그리며 헤맸다.

Takeaways

  • 기본으로 돌아가기 – 포인터에 관한 입문 자료를 다시 읽어 보라.
  • 모든 과정을 적어 보기 – 겉보기에 사소해 보이는 연산도 미묘한 디테일을 숨기고 있을 수 있다.
  • 타입을 기억하라 – 현재 다루고 있는 것이 포인터인지, 포인터의 포인터인지, 실제 값인지 정확히 아는 것이 중요하다.
  • 메모리 주소 시각화 – 메모리 레이아웃을 스케치하면 값과 주소를 혼동하는 일을 방지할 수 있다.
Back to Blog

관련 글

더 보기 »