C언어 포인터 문제는 별표의 개수를 세는 문제가 아닙니다. 먼저 변수에 저장된 값, 변수가 놓인 주소, 포인터가 현재 가리키는 대상을 분리해야 합니다. 그 뒤 한 문장씩 실행하면 배열과 증감 연산자가 섞여도 흔들리지 않습니다.

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

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 코드 추적 공부법에서 이어서 확인하세요.