SECTION 008. 포인터

1. 포인터와 포인터 변수

  • “포인터” 는 변수의 주소를 말하며, 변수의 주소를 저장할 때 사용하는 변수를 “포인터 변수” 라 한다.

1) 포인터 변수 선언

(1) 포인터 변수를 선언할 때는 자료형을 쓰고, 변수명 앞에 간접 연산자 * 를 붙인다.

  int *a;
  // a는 int형 포인터 변수이다.

(2) 포인터 변수에 주소를 저장하기 위해, 변수의 주소를 찾을 때는 변수 앞에 번지 연산자 & 를 붙인다.

  a = &b;
  // 변수 b의 주소를 포인터 변수 a에 저장한다.

(3) 실행문에서 포인터 변수에 간접 연산자 * 를 붙이면, 해당 포인터 변수가 가리키는 주소의 값을 의미한다.

  c = *a;
  // 변수 c는 포인터 변수 a가 가리키는 주소 (b의 주소) 가 가리키는 값을 의미한다.

(4) 포인터 변수는 힙 영역 에 접근하는 동적 변수이다.

  • 메모리 영역
    – ① 코드 영역 : 실행할 프로그램의 코드를 저장
    – ② 데이터 영역 : 전역 변수와 정적 변수를 저장
    – ③ 힙 영역 : 필요에 의해 동적으로 할당되는 영역
    – ④ 스택 영역 : 함수의 매개 변수와 지역 변수를 저장

2) 포인터 변수의 용도

(1) 연결된 자료 구조를 구성하기 위해 사용한다.
(2) 동적으로 할당된 자료 구조를 지정하기 위해 사용한다.
(3) 배열을 인수로 전달하기 위해 사용한다.
(4) 문자열을 표현하기 위해 사용한다.
(5) 커다란 배열에서 요소를 효율적으로 저장하기 위해 사용한다.
(6) 메모리에 직접 접근하기 위해 사용한다.

◇ 예제

  int a = 100;
  // a의 주소는 4이다.

  int *b;
  b = &a;

– &a 는 변수 a의 주소를 말한다. 즉, &a 는 4 이다.
– 4번지에는 100 이 기억되어 있다.
– 포인터 변수 b 는 변수 a 의 주소를 기억하고 있다.
– *b 는 b에 저장된 주소가 가리키는 곳에 저장된 값을 말하므로, 100 이다.

2. 포인터와 배열

1) 개념

  • 배열을 포인터 변수에 저장한 후, 포인터를 이용하여 배열의 요소에 접근할 수 있다.
  int a[5];
  int *b;

(1) 배열 위치를 나타내는 첨자를 생략하고 배열의 대표명만 지정하면 배열의 첫번째 요소의 주소를 지정하는 것과 같다.

  b = a;
  // 배열 a의 시작 주소인 a[0] 의 주소를 포인터 변수 b에 저장한다.

(2) 배열 요소에 대한 주소를 지정할 때는 일반 변수와 동일하게 & 연산자를 사용한다.

  b = &a[2];
  // 배열 a의 세 번째 요소인 a[2]의 주소를 포인터 변수 b에 저장한다.

(3) 배열의 요소가 포인터인 포인터형 배열을 선언할 수 있다.

  a[0]    a[1]    a[2]    a[3]    a[4]
  *(a+0)  *(a+1)  *(a+2)  *(a+3)  *(a+4)
  • a는 배열의 시작 주소가 저장되어 있다.
    – a의 값을 1 증가시키는 것은, 현재 a가 가진 주소에서 다음 주소를 가리킨다는 의미이다.
    – a는 정수형 자료이고, 정수형 자료의 크기는 4바이트 이므로, a가 1 증가한다는 것은 4바이트 증가한 다음 주소를 가리키는 것이다.
    – 이와 같이 p가 char형 배열의 주소를 가지고 있다면, 포인터를 1 증가시킬 때, 메모리의 주소도 1바이트 증가한 주소를 가리킨다.