본문 바로가기
C

배열과 포인터

by stdlib.h 2016. 4. 3.

배열은 가장 기본적인 자료 구조로 실용성이 높다.


포인터는 C와 다른언어를 구분하는 가장 큰 특징이다.


이 둘은 상호 보완적이면서 일정 부분에 있어서 대체가 가능하다.




C는 내부적으로 1차원 배열만 지원한다.

2차원 이상의 다차원 배열은 1차원 배열의 확장에 불과하다.

사실상은 배열의 배열인것이다.







[ ] 연산자



배열의 한 요소를 참조할 때느느 [] 연산자를 사용하며, 괄호 안에 읽고자 하는 배열의 요소의 첨자를 적는다.


사실 이 연산자가 언뜻 보기에는 구두점같지만,

실제로는 첨자연산을 하는 포인터 연산자이다.

이 연산자의 동작은 다음과 같다.

ptr 이 임의의 배열을 가리키는 포인터이고 n 이 정수일때

ptr[n] = *(ptr+n);


[]연산자가 따로 정의되어 있는 것이 아니라, 포인터 연산의

다른 표기법 일 뿐이다.


사실 ptr[n] 표현식은 컴파일러에 의해 *(ptr+n) 으로 바뀐후 컴파일된다.


연산 순위표를 보면 [] 연산자가 *보다 우선순위가 높은데, 이는 두 연산자가

달라서 그런 것이 아니라, [] 연산자의 정의에 괄호가 포함되어있기 때문이다.


따라서 arr[2][3] 은 *(*(arr+2)+3) 이 된다.


결국 [] 연산자는 포인터 연산을 한다.



포인터 배열


포인터 배열이란, 요소가 포인터형인 배열이다.

어떤 타입이 있을때, 그 타입형 포인터가 선언될 수 있고, 타입형 배열도 가능하므로, 타입형 포인터 배열도 선언할 수 있다.


예를 들어 크기 5의 정수형 포인터 배열을 선언하고 싶다면 다음과 같이 선언한다.


ex ) int *arpi[5];



차이점은 다음과 같다.


1.포인터는 변수인데, 배열은 상수이다.

ptr 은 고유의 메모리를 차지하고 있고, 언제든지 다른대상을 가리킬 수 있지만,

배열 arr은 선언할때 위치가 고정되므로, 다른 대상을 가리킬 수 없다.


2.ptr 이 가리키는 배열의 크기는 동적으로 가능하지만, arr 이 가리키는 배열은 정적이다.

ptr은 malloc 이나 realloc 으로 할당할 수 있는 반면, arr은 정적이다.



3.배열은 그 자체가 크기 때문에 함수의 인수로 전달할 수 없지만, 포인터는 대상체가 무엇이든 4바이트기 때문에 함수로 전달할 수있다.


4.배열의 요소를 읽는 것과, 포인터로 대상체를 읽는 동작은 속도 차이가 있다.

배열의 첨자 연산은 매번 배열의 선두인 arr 부터 출발하지만, 포인터는 대상체로 직접이동해서 바로 읽으므로 액세스 속도가 빠르다.

*ptr 은 ptr이 가리키는 곳을 바로 읽지만, arr[n] 은 *(arr+n) 으로 번지를 더한 후 읽어야 하므로 비교적 조금 느리다.


'C' 카테고리의 다른 글

strcpy구현  (0) 2016.04.04
strcmp 구현  (0) 2016.04.04
동적할당  (0) 2016.04.03
포인터  (0) 2016.03.31
C언어]재귀 - 피보나치 수열  (0) 2016.03.29