본문 바로가기
개발/C, C++

[c/c++] 2차원 배열, N차원 배열

by 77monkey 개발자 2023. 8. 30.
반응형

1차원 배열을 배웠으니, 2차원 배열을 비롯하여 N차원 배열에 대해서 알아보도록 하겠습니다. 혹시 배열에 대해서 처음 익히시는 거라면 1차원 배열에 대한 포스팅을 먼저 보시고 오시는 것을 추천드립니다. 아무래도 1차원 배열에서 말씀드린 내용을 기반으로 작성하기 때문에 바로 다차원 배열로 가시기에 어려움이 있을 수 있습니다.

 

 

[c/c++] 1차원 배열

배열을 다루게 되면 할 수 있는 것이 많아집니다. 1차원 배열에 대해서 설명하려고 합니다. 배열 선언과 배열 특징에 대해서 알아보도록 합시다. 배열 먼저 배열에 대해서 알아보면, 배열은 동일

77monkey.tistory.com

 

[c/c++] 1차원 배열 (2)

지난 포스팅에 이어서 오늘은 배열의 초기화, 크기에 대해서 알아보도록 하겠습니다. 혹시나 이전 포스팅을 보지 않고 오셨다면, 참고하시길 바랍니다. [c/c++] 1차원 배열 배열을 다루게 되면 할

77monkey.tistory.com


2차원 배열

2차원 배열은 1차원 배열을 2개의 인덱스를 사용하여 요소에 접근하는 배열을 의미합니다. 2차원 배열은 행과 열로 map(N

x N)을 표현하기에도 좋아 자주 쓰이는 자료구조입니다. 

 

2차원 배열 선언

2차원 배열 선언은 아래와 같이 합니다.

dataType arrayName[arraySize0][arraySize1];

dataType은 배열에 저장되는 데이터 타입을 나타내고,

arrayName은 배열의 이름을 의미하고,

arraySize0, arraySize1은 배열의 크기를 나타내는 정수입니다.

arraySize0은 "행"으로 표현을 하고, y로 표현이 됩니다. 

arraySize1은 "열"로 표현이 되고 x로 표현이 됩니다. 

x, y는 좌표를 표현할 때의 값으로 (x, y)로 보통 표현을 합니다. 행과 열, x와 y는 생각보다 헷갈리는 부분이라서 코딩할 때 실수하기 좋은 부분입니다. 헷갈리지 않게 꼭 한 번씩 생각하면서 코드를 작성하는 습관을 들이시길 바랍니다.

해당 선언에 대해서 좀 더 이해하기 쉽게 그림으로 나타내 보았습니다. 

 

더 어려우신가요? 그런데 사실 메모리에서는 위와 같이 그려지지 않고 1차원 배열처럼 쭉 나열되어 있습니다. 그림으로 표현하면 아래와 같습니다. 아무래도 아래 그림보다는 위 그림이 더 이해하는데 직관적이라서 위와 같이 표현을 하게 되었습니다. 

 

2차원 배열 예시

아무래도 예시를 보는 것이 훨씬 이해하기 쉽겠지요? 

일단 간단한 코드부터 시작하도록 하겠습니다. 

int arr[2][3];

위 코드를 그림으로 표현하면 다음과 같습니다. 

위에서 선언한 배열에 차례대로 1~6까지 입력하고, 출력하는 코드는 다음과 같습니다. 

#include <stdio.h>

int main() {

	int arr[2][3];
	int row, column;

	for (row = 0; row < 2; row++)
	{
		for (column = 0; column < 3; column++)
		{
			arr[row][column] = row * 3 + column + 1;
		}
	}

	for (row = 0; row < 2; row++)
	{
		for (column = 0; column < 3; column++)
		{
			printf("%d ", arr[row][column]);
		}
		printf("\n");
	}

	return 0;
}

코드에서 헷갈릴 수 있는 코드가 아마 아래 코드일 것 같습니다. 혹시 위에 그림을 한 번 보시고 오실 수 있으실까요? 그림을 보고 오시면 arr[row][column]에서 arr[row]는 arr[row][0] ~ arr[row][column-1]까지를 의미합니다. 즉 arr[row]는 column개를 가지고 있기 때문에 row * 3을 해주게 됩니다. 그리고 column을 더해줍니다. 이렇게 하면 0 ~ 5까지 출력이 되기 때문에 우리가 원하는 1 ~ 6까지 출력하기 위해서 1을 더해주게 됩니다.

arr[row][column] = row * 3 + column + 1;

출력 결과는 말씀드린대로 1 ~  6까지 출력하게 됩니다. 

1 2 3 
4 5 6

 

2차원 배열의 초기화

배열을 선언하고 초기화를 하는 방법은 1차원 배열 초기화에서 조금만 추가해 주면 됩니다. 중괄호를 통해서 표현을 하게 됩니다. arrayVal 다음에 나오는 값은 원소를 의미합니다. arrayVal00은 arrayVal[0][0]을 의미하고, N은 arraySize0 - 1을 의미하며 M은 arraySize1 - 1을 의미합니다.

dataType arrayName[arraySize0][arraySize1] = { 
	{ arrayVal00, arrayVal01, ..., arrayVal0M}, 
	{ arrayVal10, arrayVal11, ..., arrayVal1M}, 
	...
	{ arrayValN0, arrayValN1, ..., arrayValNM}};

간단한 배열 초기화 예시를 들면 아래와 같습니다.

#include <stdio.h>

int main() {

	int arr[2][3] = { {1, 2, 3}, {4, 5, 6} };

	for (int row = 0; row < 2; row++)
	{
		for (int column = 0; column < 3; column++)
		{
			printf("%d ", arr[row][column]);
		}
		printf("\n");
	}

	return 0;
}

출력 결과는 다음과 같게 나옵니다.

1 2 3 
4 5 6

하마터면 빠트릴 뻔 했는데, 2차 배열이라고 꼭 중괄호를 쓰지 않아도 됩니다. 왜냐하면 어차피 메모리에서는 1차원 배열처럼 이루어져 있기 때문입니다. 그래서 아래와 같이 초기화를 해줘도 무방하지만, 정확히 어떤 값을 초기화를 하는지 헷갈릴 수 있으니 중괄호를 통해서 하거나 for문 등을 돌림으로 초기화를 진행해 주시길 바랍니다. 

#include <stdio.h>

int main() {

	int arr1[2][3] = { 0 };
	int arr2[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
	int arr3[2][5] = { {0, 1, 2, 3}, {5, 6, 7, 8}};
    
	return 0;
}

 

2차원 배열의 크기

배열의 크기는 1차원에서 구했던 것과 같은 방식으로 구하게 되는데, 어떻게 구하게 되는지 헷갈릴 수 있어서 한 번 더 짚어보려고 합니다. 

배열의크기 = sizeof(배열) / sizeof(배열[0][0])

눈치를 채셨을 것 같은데, 첫 sizeof에서는 배열의 이름을 넣고, 두번째 배열에서는 값의 형태를 넣어주면 됩니다. 즉, int arr[2][3]이 있다면 arr은 배열의 주소를 의미하고, arr[2]도 배열의 주소를 의미하고, arr[2][3]이 값을 의미합니다. 

예시 코드도 한 번 살펴봅시다. 

#include <stdio.h>

int main() {

	int arr[2][3] = { 0 };

	int size = sizeof(arr) / sizeof(arr[0][0]);

	printf("sizeof(message): %d\n", sizeof(arr));
	printf("sizeof(message[0]): %d\n", sizeof(arr[0][0]));
	printf("arr size: %d\n", size);

	return 0;
}

 

N차원 배열

1차원에서 2차원으로 확장했을 때 하셨던 것을 하나씩 차원을 높여가시면 됩니다. 

보통 2차원 배열까지를 많이 활용하고, 가끔 3차원 배열까지 사용하는 것으로 보입니다. 

코드를 통해서 배열의 선언 및 초기화 방법에 대해서 알아보겠습니다. 

#include <stdio.h>

int main() {

	int arr1[2][2][2] = {
		{{0, 1},{2, 3}},
		{{4, 5},{6, 7}},
	};
	int arr2[3][2][2] = { 0 };
	int arr3[2][3][4];

	int x, y, z;

	for (z = 0; z < 2; z++) {
		for (y = 0; y < 3; y++) {
			for (x = 0; x < 4; x++){
				arr3[z][y][x] = (z * 3 * 4) + (y * 4) + x + 1;
			}
		}
	}

	for (z = 0; z < 2; z++) {
		for (y = 0; y < 3; y++) {
			for (x = 0; x < 4; x++) {
				printf("%2d ", arr3[z][y][x]);
			}
			printf("\n");
		}
		printf("\n");
	}

	return 0;
}

결과는 다음과 같습니다.

 1  2  3  4
 5  6  7  8
 9 10 11 12

13 14 15 16
17 18 19 20
21 22 23 24

 

마무리

2차원 배열에 대해서 알아보고, 2차원 배열 선언 및 배열의 크기를 구하는 방법에 대해서 알아보았습니다. 배열이 생각보다 어렵습니다. 쉬울 수도 있는데 나중에 포인터와 엮이게 되면 좀 헷갈릴 수 있으니 정리 잘 하시길 당부드립니다. 

반응형

'개발 > C, C++' 카테고리의 다른 글

[C/C++] 대입 연산자  (0) 2023.09.06
[C/C++] 산술 연산자  (0) 2023.09.05
[c/c++] 배열 룩업 테이블(look up table)  (0) 2023.08.27
[c/c++] 1차원 배열 (2)  (0) 2023.08.26
[c/c++] 1차원 배열  (0) 2023.08.25