배열도 포인터다!
C언어에서는 배열도 포인터이다. 포인터 연산자를 통해서 배열에 접근할 수 있으며 초기값은 배열의 첫번째 원소다.
예시를 통해 한번 보자.
위의 이미지를 보면 함수의 파라미터로 배열을 넣어주었다. 위의 배열은 int 배열 이므로 인트 포인터타입으로 배열을 받아온것을 볼 수 있다.
저렇게 배열을 받아오면 arr에는 배열의 첫번째 원소의 주소가 담겨져 있다.
배열의 값을 사용하려면 지난번에 했던 것처럼 역참조를 통해서 *arr이라고 쓰면 배열의 첫번째 원소의 값을 나타낸다.
(배열의 두번째, 세번째 값을 받아오고 싶으면 *(arr+i)와 같이 i에 적당한 숫자를 대입하므로써 배열의 값에 접근할 수 있다.)
동적할당
C를 공부하는 내내 이것만 기다렸다. 프로그램 실행 중에 유동적으로 메모리 공간을 할당하는 방법이다.
C에서는 다음과 같은 문법이 불가능하다. 프로그램 실행 도중에 사용자로부터 값을 받아서 그 값만큼 배열을 선언하려고 했는데 에러가 발생한다.
C에서는 arr2처럼 프로그램 시작전에 얼마정도의 메모리를 사용할 건지 미리 지정해야한다. 하지만 동적할당을 할줄 알면 프로그램 실행중에 사용되는 변수에 대해서도 메모리를 유동적으로 할당할 수 있게 된다. 동적할당의 메모리는 컴퓨터 내의 heap영역에 저장된다.
위의 사진은 arr배열의 크기를 변수 n에 대해서 동적할당 해준 모습이다. malloc 함수를 이용한 것으로 <stdlib.h> 안에 들어있다.
맨 마지막 줄을 해석하자면, int arr배열을 선언함과 동시에 n에 들어가는 숫자*4만큼의 메모리 영역을 할당해주겠다 정도로 해석할 수 있다. 왜 4냐고 묻는다면, int가 4 byte 이기 때문이다. 따라서 저렇게 쓰지 않고
int( *)malloc(n*sizeof(int))라고 해도 된다.
저렇게 배열을 선언해주면 프로그램실행중에 바뀌는 변수에 대해서 메모리가 유동적으로 변한다.
동적할당에는 malloc말고 calloc과 realloc이 있는데, calloc은 malloc 하고 똑같은 역할이지만 배열의 초기값을 0으로 초기화 해준다.
realloc은 이미 메모리가 할당된 배열의 사이즈를 바꾸고 싶을 때 사용한다.
2차원 배열
지난번에 분명 포인터가 포인터를 가르킬 수 있다고 하였다. 그걸 이용해서 2차원 배열을 만들 수 있다.
보면 더블포인터를 이용해서 A에 2차원배열을 동적할당하였다.
위에 입력받은 a_size[0] * sizeof(int *)만큼의 메모리가 동적할당 된 것이다.
더블 포인터 이므로 sizeof()안에 int 가 아니라 int*가 들어간 것을 확인할 수 있다.
저렇게 2차원 배열을 동적할당하고 for문을 이용해서 2차원 배열안에 있는 1차원 배열도 전부 동적할당을 해주어야한다.
예를 들어 [ [], [], [], [], [], [], [], [], [] , ... ,[] ] 이런 식으로 되있으므로 안에 있는 배열 안에 있는 배열도 동적할당으로 메모리 공간의 크기를 정해줘야 한다는 말이다.