1. 2차원 배열
2차원 배열은 행(row)과 열(column)로 구성된 평면 구조의 배열입니다.
2차원 배열의 개념
1차원 배열이 선형 구조라면, 2차원 배열은 표(table) 구조입니다.
실생활 예시:
- 교실의 좌석 배치
- 체스판
- 엑셀 스프레드시트
int arr[3][4]; // 3행 4열의 2차원 배열
배열 구조 시각화:
| 0열 | 1열 | 2열 | 3열 | |
|---|---|---|---|---|
| 0행 | arr[0][0] | arr[0][1] | arr[0][2] | arr[0][3] |
| 1행 | arr[1][0] | arr[1][1] | arr[1][2] | arr[1][3] |
| 2행 | arr[2][0] | arr[2][1] | arr[2][2] | arr[2][3] |
2차원 배열의 구조
• 첫 번째 인덱스: 행 번호 (세로)
• 두 번째 인덱스: 열 번호 (가로)
• 총 요소 개수 = 행 × 열
• 첫 번째 인덱스: 행 번호 (세로)
• 두 번째 인덱스: 열 번호 (가로)
• 총 요소 개수 = 행 × 열
2차원 배열 선언
자료형 배열이름[행크기][열크기];
예시:
int scores[3][4]; // 3행 4열 (총 12개 요소)
double data[2][5]; // 2행 5열 (총 10개 요소)
char table[4][3]; // 4행 3열 (총 12개 요소)
2차원 배열의 메모리 크기
int arr[3][4];
- int형: 4바이트
- 요소 개수: 3 × 4 = 12개
- 총 크기: 4 × 12 = 48바이트
실습 1
#include <stdio.h>
int main() {
int arr[2][3];
printf("배열 크기: %d바이트\n", sizeof(arr));
printf("행 개수: %d\n", sizeof(arr) / sizeof(arr[0]));
printf("열 개수: %d\n", sizeof(arr[0]) / sizeof(arr[0][0]));
return 0;
}
실행 결과 보기
배열 크기: 24바이트 행 개수: 2 열 개수: 3
- 총 크기: 2행 × 3열 × 4바이트(int) = 24바이트
- 행 개수: 전체 크기 / 1행의 크기 = 24 / 12 = 2
- 열 개수: 1행의 크기 / 1개 요소 크기 = 12 / 4 = 3
2. 2차원 배열의 초기화
2차원 배열은 여러 방법으로 초기화할 수 있습니다.
방법 1: 중괄호로 행 구분
int arr[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
| 0열 | 1열 | 2열 |
|---|---|---|
| 0행 1 | 2 | 3 |
| 1행 4 | 5 | 6 |
방법 2: 일렬로 나열 (비권장)
int arr[2][3] = {1, 2, 3, 4, 5, 6};
순서대로 채워집니다. 하지만 가독성이 떨어지므로 방법 1을 권장합니다.
방법 3: 일부만 초기화
int arr[2][3] = {
{1, 2},
{4}
};
| 0열 | 1열 | 2열 |
|---|---|---|
| 0행 1 | 2 | 0 |
| 1행 4 | 0 | 0 |
나머지는 0으로 자동 초기화됩니다.
방법 4: 행 크기 생략
int arr[][3] = {
{1, 2, 3},
{4, 5, 6}
};
⚠️ 중요
• 행 크기는 생략 가능
• 열 크기는 반드시 명시해야 함
• 행 크기는 생략 가능
• 열 크기는 반드시 명시해야 함
실습 2
#include <stdio.h>
int main() {
int arr[3][2] = {
{10, 20},
{30, 40},
{50, 60}
};
int i, j;
printf("=== 2차원 배열 출력 ===\n");
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++) {
printf("arr[%d][%d] = %d\n", i, j, arr[i][j]);
}
}
return 0;
}
실행 결과 보기
=== 2차원 배열 출력 === arr[0][0] = 10 arr[0][1] = 20 arr[1][0] = 30 arr[1][1] = 40 arr[2][0] = 50 arr[2][1] = 60
3. 2차원 배열과 반복문
2차원 배열은 중첩 for문을 사용하여 처리합니다.
기본 패턴
for (i = 0; i < 행크기; i++) {
for (j = 0; j < 열크기; j++) {
// arr[i][j] 처리
}
}
- 외부 루프: 행을 반복
- 내부 루프: 열을 반복
실습 3 - 표 형태로 출력
#include <stdio.h>
int main() {
int scores[3][4] = {
{90, 85, 88, 92},
{78, 95, 82, 88},
{85, 90, 93, 87}
};
int i, j;
printf("학생 | 국어 영어 수학 과학\n");
printf("------|-------------------\n");
for (i = 0; i < 3; i++) {
printf(" %d번 |", i+1);
for (j = 0; j < 4; j++) {
printf(" %3d", scores[i][j]);
}
printf("\n");
}
return 0;
}
실행 결과 보기
학생 | 국어 영어 수학 과학 ------|------------------- 1번 | 90 85 88 92 2번 | 78 95 82 88 3번 | 85 90 93 87
실습 4 - 학생별 평균 계산
#include <stdio.h>
int main() {
int scores[3][4] = {
{90, 85, 88, 92},
{78, 95, 82, 88},
{85, 90, 93, 87}
};
int i, j;
double sum, average;
for (i = 0; i < 3; i++) {
sum = 0;
for (j = 0; j < 4; j++) {
sum += scores[i][j];
}
average = sum / 4;
printf("학생 %d 평균: %.2f\n", i+1, average);
}
return 0;
}
실행 결과 보기
학생 1 평균: 88.75 학생 2 평균: 85.75 학생 3 평균: 88.75
4. 3차원 배열
3차원 배열은 높이(depth), 행, 열의 3차원 구조를 가집니다.
3차원 배열의 개념
int arr[2][3][4];
- 높이(depth): 2 (2개의 2차원 배열)
- 행(row): 3
- 열(column): 4
- 총 요소: 2 × 3 × 4 = 24개
3차원 배열 시각화:
[0층] [1층]
┌─────────┐ ┌─────────┐
│ 3 x 4 │ │ 3 x 4 │
│ 배열 │ │ 배열 │
└─────────┘ └─────────┘
💡 3차원 배열 이해하기
3차원 배열은 "2차원 배열을 여러 개 쌓아놓은 구조"로 생각하면 쉽습니다.
3차원 배열은 "2차원 배열을 여러 개 쌓아놓은 구조"로 생각하면 쉽습니다.
3차원 배열 선언과 초기화
int arr[2][3][4] = {
{ // 0층
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
},
{ // 1층
{13, 14, 15, 16},
{17, 18, 19, 20},
{21, 22, 23, 24}
}
};
3차원 배열 접근
arr[0][1][2] = 7; // 0층, 1행, 2열
arr[1][2][3] = 24; // 1층, 2행, 3열
실습 5
#include <stdio.h>
int main() {
int arr[2][2][3] = {
{
{1, 2, 3},
{4, 5, 6}
},
{
{7, 8, 9},
{10, 11, 12}
}
};
int i, j, k;
printf("=== 3차원 배열 출력 ===\n");
for (i = 0; i < 2; i++) {
printf("[%d층]\n", i);
for (j = 0; j < 2; j++) {
for (k = 0; k < 3; k++) {
printf("%3d ", arr[i][j][k]);
}
printf("\n");
}
printf("\n");
}
return 0;
}
실행 결과 보기
=== 3차원 배열 출력 === [0층] 1 2 3 4 5 6 [1층] 7 8 9 10 11 12
3차원 배열의 메모리 크기
#include <stdio.h>
int main() {
int arr[2][3][4];
printf("전체 크기: %d바이트\n", sizeof(arr));
printf("층 개수: %d\n", sizeof(arr) / sizeof(arr[0]));
printf("행 개수: %d\n", sizeof(arr[0]) / sizeof(arr[0][0]));
printf("열 개수: %d\n", sizeof(arr[0][0]) / sizeof(arr[0][0][0]));
return 0;
}
실행 결과 보기
전체 크기: 96바이트 층 개수: 2 행 개수: 3 열 개수: 4
2 × 3 × 4 × 4바이트(int) = 96바이트
5. 배열 포인터
배열 포인터는 배열 전체를 가리키는 포인터입니다.
포인터 배열 vs 배열 포인터
두 개념을 혼동하지 마세요!
포인터 배열:
int *arr[3]; // int형 포인터 3개를 가지는 배열
배열 포인터:
int (*ptr)[3]; // int형 배열(크기 3)을 가리키는 포인터
구분 방법
•
•
•
int *arr[3] → 배열이 먼저 (포인터 배열)•
int (*ptr)[3] → 괄호로 포인터가 먼저 (배열 포인터)
배열 포인터의 사용
배열 포인터는 2차원 배열을 가리킬 때 주로 사용합니다.
int arr[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
int (*ptr)[3]; // 크기 3인 int 배열을 가리키는 포인터
ptr = arr; // arr의 첫 번째 행을 가리킴
실습 6
#include <stdio.h>
int main() {
int arr[2][3] = {
{10, 20, 30},
{40, 50, 60}
};
int (*ptr)[3]; // 배열 포인터 선언
ptr = arr; // arr의 첫 번째 행을 가리킴
int i, j;
printf("=== 배열 포인터로 접근 ===\n");
for (i = 0; i < 2; i++) {
for (j = 0; j < 3; j++) {
printf("%d ", ptr[i][j]);
}
printf("\n");
}
return 0;
}
실행 결과 보기
=== 배열 포인터로 접근 === 10 20 30 40 50 60
배열 포인터의 연산
int arr[3][4];
int (*ptr)[4] = arr;
ptr; // arr[0]을 가리킴 (0행)
ptr + 1; // arr[1]을 가리킴 (1행)
ptr + 2; // arr[2]를 가리킴 (2행)
배열 포인터를 1 증가시키면 다음 행을 가리킵니다.
6. 종합 실습
문제 1 - 2차원 배열 크기 (기초)
문제 1
int arr[4][5]의 전체 크기는 몇 바이트입니까?
다차원 배열
문제 2 - 2차원 배열 접근 (기초)
문제 2
다음 코드의 실행 결과는?
다차원 배열
#include <stdio.h>
int main() {
int arr[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
printf("%d", arr[1][2]);
return 0;
}
문제 3 - 2차원 배열 초기화 (기초)
문제 3
다음 코드의 실행 결과는?
다차원 배열
#include <stdio.h>
int main() {
int arr[2][3] = {
{10, 20},
{30}
};
printf("%d", arr[0][2] + arr[1][1]);
return 0;
}
문제 4 - 2차원 배열 합계 (중급)
문제 4
다음 코드의 실행 결과는?
다차원 배열
#include <stdio.h>
int main() {
int arr[2][2] = {
{5, 10},
{15, 20}
};
int i, j, sum = 0;
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
sum += arr[i][j];
}
}
printf("%d", sum);
return 0;
}
문제 5 - 3차원 배열 (중급)
문제 5
다음 코드의 실행 결과는?
다차원 배열
#include <stdio.h>
int main() {
int arr[2][2][2] = {
{{1, 2}, {3, 4}},
{{5, 6}, {7, 8}}
};
printf("%d", arr[1][0][1] + arr[0][1][1]);
return 0;
}
문제 6 - 대각선 합 (고급)
문제 6
다음 코드에서 3×3 배열의 대각선 합은?
다차원 배열
#include <stdio.h>
int main() {
int arr[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int i, sum = 0;
for (i = 0; i < 3; i++) {
sum += arr[i][i];
}
printf("%d", sum);
return 0;
}
핵심 요약
1. 2차원 배열
• 선언:
• 행과 열로 구성된 표 구조
• 접근:
• 초기화: 중괄호로 행 구분
2. 2차원 배열 순회
• 중첩 for문 사용
• 외부 루프: 행 반복
• 내부 루프: 열 반복
3. 3차원 배열
• 선언:
• 2차원 배열을 쌓아놓은 구조
• 3중 중첩 for문으로 순회
4. 배열 포인터
• 선언:
• 배열 전체를 가리키는 포인터
• 2차원 배열 접근에 활용
• 포인터 배열과 구분 필수
5. 메모리 크기
• 2차원: 행 × 열 × 자료형 크기
• 3차원: 높이 × 행 × 열 × 자료형 크기
•
• 선언:
int arr[행][열];• 행과 열로 구성된 표 구조
• 접근:
arr[i][j]• 초기화: 중괄호로 행 구분
2. 2차원 배열 순회
• 중첩 for문 사용
• 외부 루프: 행 반복
• 내부 루프: 열 반복
3. 3차원 배열
• 선언:
int arr[높이][행][열];• 2차원 배열을 쌓아놓은 구조
• 3중 중첩 for문으로 순회
4. 배열 포인터
• 선언:
int (*ptr)[열크기];• 배열 전체를 가리키는 포인터
• 2차원 배열 접근에 활용
• 포인터 배열과 구분 필수
5. 메모리 크기
• 2차원: 행 × 열 × 자료형 크기
• 3차원: 높이 × 행 × 열 × 자료형 크기
•
sizeof()로 계산 가능
PREVIOUS9. 포인터와 배열의 관계
NEXT11. 문자열과 함수