티스토리 뷰

# 2차원 배열 (TWO-DIMENSIONAL ARRAYS)


 2차원 배열은 사실 일차원 배열이다. 단지, 배열의 요소가 1차원 배열로 이루어져 있을 뿐이다. 2차원 배열을 선언할 때 우리는 주로 int arr[3][5] 와 같이 선언한다. 하지만 우리는 실제로 길이가 3인 배열 x를 생성했을 뿐이고, x의 각 요소들이 길이가 5인 일차원 배열일 뿐이다. 아래 그림을 살펴보자.

  이 그림은 2차원 배열의 메모리 구조를 보여주고 있다. 먼저, 회색으로 통째로 칠해진 블럭을 보면 3개의 포인터를 가질 수 있는 크기로 되어 있다. 그리고 그 포인터를 따라가면, 5개의 integer 변수를 포함할 수 있는 녹색블럭이 각 3개가 나온다.


 C 에서 arr[i][j] 를 찾아가는 과정은 이렇다. 첫째로, x[i] 포인터에 접근한다. 이 포인터는 배열의 i 번째 행의 0번째 요소의 주소값을 가진다. x[i] 포인터에 접근한 후 포인터의 주소에 j * sizeof (int) 만큼을 더해준다.


 아래의 예제 프로그램을 통해서 2차원 배열을 어떻게 동적으로 생성하고 다루는지 살펴보도록 하자.

/*************************************************
 ** MAT program comments
*************************************************/

#include <stdio.h>
#include <stdlib.h>

#define MALLOC(p,s) if (!((p) = malloc(s))) { fprintf(stderr, "메모리 부족(Insufficient memory)"); exit(EXIT_FAILURE);}

int** make2dArray(int rows, int cols)
{
	/* 2차원 배열(two dimensional rows x cols array)을 생성한다. */
	int **x, i;

	/* 행을 가리키는 포인터의 메모리를 얻는다. */
	/* get memory for row pointers */
	MALLOC(x, rows * sizeof(*x));
	// (*x)의 자료형은 *(int **) = int * 연산에 의해 int *로 정해진다.
	// 포인터의 크기는 32bits 운영체제에선 4bytes이므로 4bytes가 동적 할당된다.

	/* 각 행에 대한 메모리를 얻는다. (열에 해당하는 메모리를 얻는다.) */
	/* get memory for each row */
	for (i = 0; i < rows; i++)
		MALLOC(x[i], cols * sizeof(**x));
	// (**x)의 자료형은 **(int **) = int 연산에 의해 int로 정해진다.
	// int는 4bytes의 자료형이다. 따라서 4bytes * cols 만큼 메모리가 동적 할당 되어
	// x[i]에 루프 별로 동적 할당된 메모리의 시작주소가 저장된다.
	
	return x;
}

/*************************************************
 ** End Line
*************************************************/

 2중 포인터의 사용이 낯설게 느껴지고 어려울 수 있지만 주석에 있는 문장을 살펴보고 적용해보면 이해가 될 것이다. (int *)인 자료형한 번 간접지정(*) 하게되면, *가 하나 지워진다고 생각하면 편하다. int * 자료형을 한 번 간접지정하면 int 자료형이 나오고, 같은 원리로 int ** 자료형을 한 번 간접지정하면 int * 자료형이 나오게 된다.


 이 코드는 위의 그림에서 설명했던 것처럼 x[ i ]가 각 행에 대한 포인터이며, 각 행을 구성하는 열들에 대한 메모리를 할당하는 프로그램이다. int *에 해당하는 것이 행이고, int **에 해당하는 것이 행에 대한 각 열이라고 생각할 수 있다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday