[C] 2차원 배열
배열안에 배열을 넣어보면?
파이썬에서는
a = [
[0,0,0]
[0,0,0]
[0,0,0]
]
위와 같이 바로 2차원으로 배열을 선언할 수 있다.
그럼 C언어 에서는?
int a[3][3];
C언어에서는 위와 같이 선언하게 된다.
이렇게 할당된 배열을 인덱스를 통해 위치를 나타내면 아래와 같다.
{
{a[0][0],a[0][1],a[0][2]}
{a[1][0],a[1][1],a[1][2]}
{a[2][0],a[2][1],a[2][2]}
}
즉, 첫번째 인덱스에는 행, 두번째 인덱스에는 열이 들어간다고 생각하면 편하다.
중학교때 행렬 배울때 원소의 표기를 aij로 하는 것과 같은 이치로 보면 된다.
2차원 배열의 순회, 저장, 출력
2차원 배열은 주로 for문을 두 개를 사용해서 순회하는 형태를 사용한다.
#include <stdio.h>
#pragma warning (disable : 4996)
#define row 3
#define col 4
int main() {
int a[row][col]; // 2차원 배열의 선언 메모리 3 x 4 = 12개 할당.
// 사실 int a[12];이랑 메모리 할당량은 똑같음.
// 2차원 배열은 행 단위로 데이터를 처리하는 경우에 주로 사용
int i, j, num = 1;
// 저장
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++){
a[i][j] = num++;
}
}
// 출력
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++){
printf("%5d", a[i][j]);
}
puts("");
}
return 0;
}
위 코드는 1부터 12까지 번호를 2차원 배열에 순차적으로 저장한 뒤 출력하는 코드이고,
// row = 3, col = 4
1 2 3 4
5 6 7 8
9 10 11 12
실행결과는 위와 같이 나온다.
행과 열의 저장 순서를 바꾸기 1 (세로순)
for문의 순서를 바꿔서 다음과 같이 열 순서대로 저장되는 것을 바꿀 수 있다.
// 저장
for (j = 0; j < col; j++) {
for (i = 0; i < row; i++){
a[i][j] = num++;
}
}
출력 코드는 건드리지 않았다.
그리고 결과는
// col = 5, row = 5
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25
// col = 4, row = 3
1 4 7 10
2 5 8 11
3 6 9 12
그러하다.
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++){
a[i][j] = 1 + i + (j * col);
}
}
혹은 저장 과정을 위와 같이 해도 결과는 같다.
행과 열의 저장 순서를 바꾸기 2 (지그재그)
지그재그 순서로 나타내려면 어떻게 하면 될까?
// 저장
for (i = 0; i < row; i++) {
if (i % 2 == 0) {
for (j = 0; j < col; j++) {
a[i][j] = num++;
}
}
else if (i % 2 == 1) {
for (j = col - 1; j >= 0; j--) {
a[i][j] = num++;
}
}
}
필자는 홀수행이냐 짝수행이냐 여부에 따라서 행의 순위방향이 바뀌도록 설정했다. 위의 코드가 그 모습이다.
// row = 5, col = 5
1 2 3 4 5 // 0번행 좌 -> 우
10 9 8 7 6 // 1번행 우 -> 좌
11 12 13 14 15 // 2번행 좌 -> 우
20 19 18 17 16 // 3번행 우 -> 좌
21 22 23 24 25 // 4번행 좌 -> 우
결과는 위와 같다.
// 저장
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
if (i % 2 == 0) {
a[i][j] = num++; // 왼쪽부터 저장
}
else {
a[i][col - j] = num++; // 오른쪽부터 저장
}
}
}
혹은 위와 같이 j에 대한 for문 안에서 조건을 부여하는 방법도 유효하다.
저장하는 방향을 서로 다르게 하면 된다.
그럼 다른 방법은 없을까?
1번행, 3번행에서 ㄷ자를 뒤집은 모양대로 순회를 한다고 생각해보면 아래와 같이 코드를 짤 수 있다.
// 저장
for (i = 0; i < row ; i++) {
for (j = 0; j < col; j++) { //좌 -> 우 순회
a[i][j] = num++;
}
i++; // 다음 행으로 넘어감.
if (i == row) {
break; //방금 것이 마지막 행이었을 경우 break
}
for (j = col - 1; j >= 0; j--) { //우 -> 좌 순회
a[i][j] = num++;
}
}