포인터와 배열은 깊은 관계가 있는데 사실 배열의 이름이 바로 포인터이다. 다음 예를 보자.
0603-01.c |
#include <stdio.h> int main() { int iaa[] = {11,22,33,44,55}; int ib = 4; printf("iaa : %p\n", iaa); //(1) printf("*iaa : %d\n", *iaa); //(2) printf("*(iaa+ib) : %d\n", *(iaa+ib)); //(3) printf("iaa[ib] : %d\n", iaa[ib]); //(4) } |
iaa : 0028ff08 *iaa : 11 *(iaa+ib) : 55 iaa[ib] : 55 |
이 예에서 (1)의 결과 를 보면 포인터(주소)값이 찍히는 것을 알 수 있으며 (2), (3), (4)의 결과를 보면 배열명은 내부적으로 배열의 첫 번째 요소의 포인터(주소)임을 알 수 있다. 그래서 배열의 첫 번째 요소를 참조하는 다음 표현식은 모두 같은 것들이다.
*iaa
*(iaa + 0)
iaaa[0]
마찬가지로 배열의 5번째 요소는
iaa[5]
*(iaa+5)
로 표현할 수 있다.
또 다른 예를 보자.
0603-02.c |
#include <stdio.h> int main() { int iaa[] = {11,22,33,44,55}; int *ip = iaa; for(int k=0; k<5; k++){ printf("iaa[%d]:%d, ", k, ip[k]); //(1) } printf("\n"); for(int k=0; k<5; k++){ printf("iaa[%d]:%d, ", k, *(ip+k)); //(2) } printf("\n"); for(int k=0; k<5; k++){ printf("iaa[%d]:%d, ", k, *(ip++)); //(3) } } |
iaa[0]:11, iaa[1]:22, iaa[2]:33, iaa[3]:44, iaa[4]:55, iaa[0]:11, iaa[1]:22, iaa[2]:33, iaa[3]:44, iaa[4]:55, iaa[0]:11, iaa[1]:22, iaa[2]:33, iaa[3]:44, iaa[4]:55, |
여기서 (1)과 (2)는 완전히 같은 코드이다. 즉 ip[k] 와 *(ip+k)는 완전히 동일한 표현식이다. 하지만 (3)에서는 앞의 경우들과 달리 ip값이 직접 증가하여 변한다는 점이 다르다. 하지만 배열명에 정수를 더하거나 뺄 수 없다. 즉 iaa++, --iaa 과 같은 표현식은 에러를 발생시킨다. 배열 포인터를 직접 증감시킬 수 없으므로 다른 포인터를 변열 명으로 초기화 한 후 그 포인터를 조작해야 한다.
배열과 포인터의 차이점을 요약하면 다음과 같다.
배열은 메모리가 자동으로 생성되지만 포인터는 메모리를 할당해야 한다.
배열은 주소 이동이 불가능하지만 포인터는 가능하다.
배열은 크기가 ‘데이터형×배열크기’ 이지만 포인터는 2 또는 4바이트이다.
‘배열명은 첫 번째 요소의 포인터값을 갖는 상수’라는 사실은 확실히 알아두어야 한다.
'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글
8.1 구조체의 정의 (0) | 2016.04.15 |
---|---|
6.5 문자열과 포인터 (0) | 2016.04.15 |
6.1 포인터 개요 (0) | 2016.04.15 |
5장 연습문제 (0) | 2016.04.11 |
C언어의 문자열 (0) | 2016.04.11 |