시험장에서 C언어 포인터 코드를 마주치면 왜 눈앞이 아득해질까요? 눈으로 대충 변수와 별표(*)를 훑어보며 머릿속으로 어림짐작하기 때문입니다. 포인터는 암기 과목이 아니라 메모리 추적 훈련입니다. 변수에 담긴 실제 값, 그 변수가 차지한 메모리 주소, 포인터가 가리키는 대상을 3칸으로 정확히 쪼개는 손훈련이 되어 있지 않으면 단 1줄의 증감 연산자에도 5점을 통째로 날리게 됩니다.

값·주소·가리키는 대상을 서로 다른 칸에 적습니다

int n = 7;과 int *p = &n;이 있다면 n의 값은 7이고, p의 값은 n의 주소이며, *p는 그 주소에 저장된 7입니다. 이 세 문장을 한꺼번에 “p는 n”이라고 외우면 대입문이 하나만 바뀌어도 추적이 꼬입니다.

표현읽는 기준
&n변수 n이 저장된 메모리 주소
p포인터 변수 p에 저장된 주소
*pp가 가리키는 주소에 저장된 값
&p포인터 변수 p 자체가 저장된 주소

선언의 별표와 식의 별표를 같은 역할로 읽지 않습니다

int *p의 별표는 p를 정수형 포인터로 선언합니다. 반면 실행식의 *p는 p가 가리키는 값을 읽거나 바꾸는 역참조 연산입니다. 선언문인지 실행문인지 먼저 구분하면 포인터 문법의 절반은 정리됩니다.

배열 이름은 첫 원소를 찾는 기준으로 추적합니다

일반적인 식에서 배열 이름은 첫 원소를 가리키는 포인터로 변환됩니다. 따라서 a[i]와 *(a + i)는 같은 원소를 나타냅니다. 다만 배열 자체와 포인터 변수가 완전히 같은 객체라는 뜻은 아닙니다. 시험에서는 원소 이동 단위가 자료형 크기에 따라 달라진다는 점까지 확인하세요.

손으로 쓰는 추적표
  1. 대상p가 a[0], a[1] 중 어디를 가리키는지 적는다.
  2. 식의 값역참조한 값과 연산에 사용된 값을 적는다.
  3. 변경포인터가 이동했는지, 원소값이 바뀌었는지 구분한다.
  4. 출력그 문장에서 실제로 출력된 값만 따로 누적한다.

별표와 증감 연산자의 결합 순서를 괄호로 다시 씁니다

식먼저 확인할 변화
*p++*(p++)로 해석하며 현재 값을 사용한 뒤 포인터가 이동
(*p)++포인터는 그대로 두고 가리키는 값을 사용한 뒤 증가
*++p포인터를 먼저 이동한 뒤 새 위치의 값을 역참조
++*p가리키는 값을 먼저 증가시킨 뒤 그 결과를 사용

머릿속으로만 구분하지 말고 괄호를 직접 보충하세요. 같은 줄에 출력문이 있다면 “표현식에 사용된 값”과 “문장이 끝난 뒤 저장된 값”도 따로 적어야 합니다.

마지막에는 주소 이동과 값 변경을 각각 검산합니다

선언과 역참조의 별표를 구분했는가p와 *p를 같은 값처럼 쓰지 않았는가배열 인덱스와 포인터 이동 위치가 같은가후위 증감 전 값을 식에 사용했는가함수에 넘긴 것이 값인지 주소인지 확인했는가최종 출력의 공백과 개행까지 적었는가

포인터만 따로 오래 보는 것보다 짧은 코드를 한 줄씩 실행하는 편이 낫습니다. 전체 언어의 추적 순서는 C·Java·Python 코드 추적 공부법에서 이어서 확인하세요.