프로그래밍 언어 활용
포인터와 배열
원본 82~83쪽
배열을 포인터 변수에 저장한 후 포인터를 이용해 배열의 요소에 접근할 수 있다.
배열 위치를 나타내는 첨자를 생략하고 배열의 대표명만 지정하면 배열의 첫 번째 요소의 주소를 지정하는 것과 같다.
배열 요소에 대한 주소를 지정할 때는 일반 변수와 동일하게 & 연산자를 사용한다. int a[5], *b;
b = a; → 배열의 대표명을 적었으므로 a 배열의 시작 주소인 a[0]의 주
소를 b에 저장한다.
b = &a[0]; → a 배열의 첫 번째 요소인 a[0]의 주소(&)를 b에 저장한다.
a[0]
a[1]
a[3]
a[4]
← 배열 표기 방법
| 첫 번째 | 두 번째 | 세 번째 | 네 번째 | 다섯 번째 |
|---|
배열 a
*(a+0)
*(a+1)
*(a+2)
*(a+3)
*(a+4)
← 포인터 표기 방법
배열의 요소가 포인터인 포인터형 배열을 선언할 수 있다.
main( )
{
int a[5];
5개의 요소를 갖는 정수형 배열 a를 선언한다. 선언할 때 사용할 개수를 선언하고, 사용할 때는 첨자를 0부터 사용한다. 정수형 변수 i를 선언한다.
int i;
int *p; ❶
for (i = 0; i < 5; i++)
반복 변수 i가 0에서 시작하여 1씩 증가하면서 5보다 작은 동안 ❷번을 반복 수행한다.
a[i] = i + 10; ❷
p = a; ❸
for (i = 0; i < 5; i++)
반복 변수 i가 0에서 시작하여 1씩 증가하면서 5보다 작은 동안 ❹번을 반복하여 수행한다. 결과
printf("%d ", *(p+i)); ❹
}
10 11 12 13 14
코드의 실행 과정에 따라 메모리의 변화를 그려보면 다음과 같다. ❶ 정수형 변수가 저장된 곳의 주소를 기억할 정수형 포인터 변수 p를 선언한다.
메모리
주소0000⋮a 1000
| a[0] | a[1] | a[2] | a[3] | a[4] |
p
⋮9999
❷ 배열 a의 i번째에 i+10을 저장한다. i는 0~4까지 변하므로 배열 a에 저장된 값은 다음과 같다.
메모리
주소0000⋮a 1000
| 10 | 11 | 12 | 13 | 14 |
| a[0] | a[1] | a[2] | a[3] | a[4] |
p
⋮9999
❸ 배열명 a는 배열의 주소이므로 포인터 변수 p에는 배열 a의 시작 위치가 기억된다. 배열의 이름은 주소이므로 ‘p = &a’처럼 입력하지 않도록 주의해야 한다.
메모리
주소0000⋮a 1000
| 10 | 11 | 12 | 13 | 14 |
| a[0] | a[1] | a[2] | a[3] | a[4] |
| 1000 |
p
⋮9999
❹ p에 저장된 값은 정수형 배열의 시작 주소이다. p의 값을 1 증가 시킨다는 것은 현재 p가 가리키고 있는 정수형 자료의 주소에서 다음 정수형 자료의 주소로 가리키는 주소를 증가시킨다는 것이다. 정수형 자료의 크기는 4바이트이므로 다음 물리적 메모리의 주소는 4Byte 증가한 곳을 가리키는 것이다. p에 저장된 배열의 시작 주소에서 1번지씩, 즉 4Byte씩 증가시키는 것을 그림으로 표현하면 다음과 같다.
메모리
주소0000⋮a 1000
| 4Byte▶ | 4Byte▶ | 4Byte | 4Byte | 4Byte |
| 10 | 11 | 12 | 13 | 14 |
| p + 0 1000 | p + 1 1004 | p + 2 1008 | p + 3 1012 | p + 4 1016 |
| 1000 |
p
⋮9999
p+0 : 배열의 시작 주소에 0을 더했으므로, 배열의 시작 주소인 ‘1000’ 번지 그대로이다.
(p+0) : ‘1000’ 번지의 값은 10이다. 10을 출력한다.
p+1 : ‘1000’에서 한 번지 증가한 주소는 ‘1004’ 번지 이다.
(p+1) : ‘1004’ 번지의 값은 11이다. 11을 출력한다.
p+2 : ‘1000’에서 두 번지 증가한 주소는 ‘1008’ 번지 이다.
(p+2) : ‘1008’ 번지의 값은 12이다. 12를 출력한다.
⋮