1. 포인터 배열(Array of Pointer)이란 ?
= 요소가 포인터로 이루어진 배열
ex) 크기 5인 정수형 포인터 배열
int *arpi[5]; // 정수형 포인터 5개가 모여 이루어진 배열
#include<stdio.h> #include<stdlib.h>
void main(void) { char *arps[]={"고양이","개","오랑우탄","돼지","지렁이"}; int i;
for (i=0;i<5;i++) { printf("%s\n",arps[i]); } } |
각 문자열들은 메모리상에 흩어져서 존재 위치에 상관없이 이 문자열들에 대한 반복처리 가능 이렇게 만들어진 문자열 배열을 [ Ragged 배열 ] 이라 한다. (장점 : 개별 문자열의 길이가 달라도 낭비되는 메모리가 없다) |
2. 포인터 배열의 활용
3개 학급의 성적 처리를 할 수 있는 예제
#include<stdio.h> #include<stdlib.h>
void main(void) { int *ar[3]; int num[3]; int i;
for (i=0;i<3;i++) { printf("%d반의 학생수를 입력하세요 : ",i+1); scanf("%d",&num[i]); ar[i]=(int *)malloc(num[i]*sizeof(int)); }
// 여기서 성적을 처리한다.
for (i=0;i<3;i++) { free(ar[i]); } } |
1. 각 학급의 학생수를 입력받아 num배열에 저장 2. 입력된 수 만큼 메모리 동적할당 3. ar배열에 차례로 그 번지를 저장 4. ar배열이 가리키는 포인터들은 각 학급 학생들의 성적을 저장할 수 있는 배열이 됨 . 5. 성적 처리가 끝난 후 free함수로 해제 이렇게 만들어진 ar배열은 2차 정수형 배열같이 사용 가능 ex) ar[0][1] -> 0번째 학급의 1번째 학생의 성적 |
3. 포인터와 배열
int ar[n]; -> ar[n]은 n개의 정수형 변수를 모아놓은 배열이다. 여기서 n은 변수가 아니라 상수. sizeof(ar) = 20
int *pi -> pi는 정수형 변수 하나의 위치를 가리킬 수 있는 포인터
But! 동적 메모리 할당으로 pi로도 정수형 배열을 가리킬 수 있다
pi=(int *)malloc(n*sizeof(int));
그림으로 도식화해보면
pi는 ar과 똑같은 자격을 가지며 정수형 배열처럼 행세할 수 있다.
pi나 ar이나 둘 다 배열의 선두 번지를 가리키며 ar[2]로 2번째 요소를 읽을 수 있듯이 pi[2]로도 2번째 요소를 읽을 수 있다.
그렇다면 다른점은?
① 포인터 = 변수 vs 배열 = 상수이다.
pi는 고유의 메모리를 차지하고 있고 언제든지 다른 대상을 가리킬 수 있지만 ar은 선언할 때 그 위치가 이미 고정되므로 다른 대상을
가리킬 수 없다. ar로는 오로지 배열의 선두 번지를 읽을 수 있을 뿐이며 이 선두 번지를 기준으로 하여 배열 요소를 읽는다.
② pi가 가리키는 배열의 크기는 동적으로 결정가능 vs ar이 가리키는 배열의 크기는 선언할 때 정적으로 결정
고정된 길이의 배열이 필요하면 int ar[n]; 선언문으로 배열을 생성하는 것이 편리하고 가변 길이의 배열이 필요하면 int *형의 포인터 변수를
선언한 후 malloc으로 할당해서 사용해야 한다. 포인터로 할당한 배열은 실행중에라도 realloc으로 크기를 재할당하여 변경할 수 있다.
③ 배열은 그 자체가 크기 때문에 함수의 인수로 전달할 수 없다 vs 포인터는 대상체가 무엇이든간에 4바이트의 크기밖에 차지하지 않으므로 함수로 전달할 수 있다.
그래서 배열을 함수로 전달할 때는 반드시 포인터를 사용해야 한다.
④ 배열로 요소를 읽는 것과 포인터로 대상체를 읽는 동작은 속도 차이가 있다.
배열의 첨자 연산은 매번 배열 선두에서부터 출발하지만 포인터는 대상체로 직접 이동해서 바로 읽으므로 액세스 속도가 빠르다. *pi는 pi가 가리키는 곳을 바로 읽지만 ar[n]은 *(ar+n)으로 일단 번지를 더한 후 읽어야 하므로 조금 느리다. 대단한 속도 차이는 아니지만 대규모의 반복적인 루프에서는 이 속도차도 결코 무시 못할 정도로 크다. 대략 포인터가 배열보다 두 배 정도 빠르다.
심화
I. int *api[5]; -> 위에서 살펴봤던 포인터 배열이다
포인터배열의 각 요소들은 정수형 변수 or 동적 할당된 정수형 배열을 가리킬 수 있다
II. int **papi; -> 위와 같은 api같은 포인터 배열을 가리킬 수 있다.
출처 : www.soen.kr
'Engineering > Data Sturcture' 카테고리의 다른 글
포인터공부7 - 구조체 (0) | 2016.03.19 |
---|---|
포인터공부4 - 이중포인터 (0) | 2016.03.16 |
포인터공부3 - 동적메모리 할당 (0) | 2016.03.15 |
포인터공부 2 (0) | 2016.03.15 |
포인터공부 1 (0) | 2016.03.15 |