[C] 2차원 배열

방법이있지·2025년 6월 9일
post-thumbnail

2차원 배열은 1차원 배열을 요소로 갖는 배열입니다. 행렬을 떠올리시면 이해가 빠를 겁니다.

2차원 배열

2차원 배열의 선언과 요소 사용

  • 1차원 배열을 요소로 갖는 배열
  • 선언: 자료형 배열명[행의 수][열의 수]
    • e.g., int array[3][4]
  • 접근: 배열명[행 인덱스][열 인덱스]
    • 인덱스는 0부터 행 / 열의 수 - 1까지의 값을 가짐
  • 각 행(1차원 배열)을 부분배열이라고도 부름

🐈 2차원 배열을 이용해, 음식점별 메뉴 가격을 저장하는 프로그램을 만들어봅시다.

  • 예를 들어, 음식점 3곳의 4개 메뉴 가격을 3행 4열의 2차원 배열에 저장할 수 있겠죠.
  • 이후 반복문으로 배열을 순회하며, 각 메뉴의 총액, 평균 가격을 계산할 수 있습니다.
// 음식점 3개의 가격 4개를 저장할 배열
int price[3][4];

// 가격 입력
for (int i = 0; i < 3; i++){
    printf("메뉴 4개의 가격 입력: ");
    for (int j = 0; j < 4; j++){
        scanf("%d", &price[i][j]);
    }
}

int total;      // 총액을 저장할 변수
double mean;    // 평균을 저장할 변수

// 각 메뉴의 가격 총액 및 평균을 계산하고 출력
for (int j = 0; j < 4; j++){
    total = 0;
    for (int i = 0; i < 3; i++){
        total += price[i][j];
    }
    mean = total / 3.0;
    printf("총액 %d, 평균 %.2lf\n", total, mean);
}

// [입력]
// 메뉴 4개의 가격 입력: 2000 4000 5000 6000
// 메뉴 4개의 가격 입력: 2500 3800 5500 5800
// 메뉴 4개의 가격 입력: 2300 4200 5200 6200
// [출력]
// 총액 6800, 평균 2266.67
// 총액 12000, 평균 4000.00
// 총액 15700, 평균 5233.33
// 총액 18000, 평균 6000.00
  • 행의 수는 배열 전체의 크기를 부분배열 하나의 크기로 나누어 구함
    • sizeof(price) / sizeof(price[0])
  • 열의 수는 부분배열 하나의 크기를 원소 하나의 크기로 나누어 구함
    • sizeof(price[0]) / sizeof(price[0][0])

메모리에서의 2차원 배열

  • 2차원 배열의 요소는 메모리상 각 행 단위로 연속적으로 배치되며, 한 행씩 차례대로 메모리에 할당됨

  • price는 각 행에 해당되는 price[0], price[1], price[2]를 부분배열로 가짐
  • 이때 각 부분배열명은 해당 행의 첫 번째 요소의 주소로 해석됨
    • 1차원 배열의 배열명이 첫 요소의 주소로 해석되는 것과 동일
    • e.g., price가 100번지부터 할당됐을 때, price[0] -> 100, price[1] -> 116, price[2] -> 132

2차원 배열 초기화

  • 중괄호 쌍을 2개 써서 초기화
  • 일부 값을 생략하면 자동으로 0으로 채워짐
int price[3][4] = {
    {4500, 6000},
    {2000, 5000, 7000},
    {1500}
};

for (int i = 0; i < 3; i++){
    for (int j = 0; j < 4; j++){
        printf("%7d", price[i][j]);
    }
    printf("\n");
}

// [출력]
//    4500   6000      0      0
//    2000   5000   7000      0
//    1500      0      0      0
  • 행의 수는 생략할 수 있음: 컴파일러가 중괄호의 개수로 행의 수 결정
    • int arr[][4] = {{1}, {2, 3}, {4, 5, 6}} -> 자동으로 행 3개로 결정됨
    • 단, 열의 수는 생략할 수 없음
  • 1차원 배열처럼 중괄호를 1개만 사용할 시, 행 단위로 차례대로 나열됨
    • int arr[2][2] = {1, 2, 3, 4}int arr[2][2] = {{1, 2}, {3, 4}}와 동일
    • 이 점을 이용해, int arr[3][4] = {0}으로 모든 값을 0으로 초기화 가능

2차원 char 배열

  • 하나의 문자열을 저장하기 위해선 char 배열이 필요
  • 여러 문자열을 저장하려면 char 배열이 여러 개 필요
    • 2차원 char 배열을 사용할 수 있음

입력 받기

char coffee[4][11];
int count = sizeof(coffee) / sizeof(coffee[0]); // 행의 수

// 부분배열명 coffee[i]는 첫 char 요소의 주소
for (int i = 0; i < count; i++){
    scanf("%s", coffee[i]);
}

for (int i = 0; i < count; i++){
    printf("%s ", coffee[i]);
}

// [입력] espresso americano latte cappuccino
// [출력] espresso americano latte cappuccino

  • 부분배열명 coffee[i]은 각 부분배열의 첫 원소의 주소로 해석됨
    • 따라서 scanf에 입력할 때 주소 연산자를 붙일 필요가 없음

2차원 char형 배열의 초기화

  • 문자열 상수를 이용해 한 행씩 초기화할 수 있음
    • e.g., char arr[4][20] = {"aaa", "bbb", "ccc"}

🐈 이를 이용해 앞선 음식점 가격 프로그램을 개선해봅시다. 각 메뉴에 이름을 붙여줍시다.

  • char foods[4][20] = {"어묵", "김밥", "떡볶이", "순대"} 식으로
  • 이때 한국어는 한 글자가 1바이트가 아닌 3바이트로 저장됨에 유의하세요. (UTF-8 기준)
  • 그래서 한글 문자열을 저장하려면 배열의 열 크기를 더 넉넉하게 잡아야 합니다. 그래서 열의 수를 20으로 넉넉히 잡았습니다.

또봇에 나오는 어묵 김밥 떡볶이 순대 노래가 생각나서 그걸로 했습니다

// 음식점 3개의 가격 4개를 저장할 배열
int price[3][4];

// 각 메뉴의 이름을 저장하는 2차원 char 배열 초기화
char foods[4][20] = {"어묵", "김밥", "떡볶이", "순대"};

// 가격 입력
for (int i = 0; i < 3; i++){
    printf("메뉴 4개의 가격 입력: ");
    for (int j = 0; j < 4; j++){
        scanf("%d", &price[i][j]);
    }
}

int total;
double mean;

// 출력
for (int j = 0; j < 4; j++){
    total = 0;
    for (int i = 0; i < 3; i++){
        total += price[i][j];
    }
    mean = total / 3.0;
    printf("%s: 총액 %d, 평균 %.2lf\n", foods[j], total, mean);
}

// [입력] 앞 예제와 동일해 생략
// [출력]
// 어묵: 총액 6800, 평균 2266.67
// 김밥: 총액 12000, 평균 4000.00
// 떡볶이: 총액 15700, 평균 5233.33
// 순대: 총액 18000, 평균 6000.00

3차원 이상의 배열

  • 같은 원리로 3차원 이상의 배열도 선언 및 사용할 수 있음
    • e.g., 3차원 배열은 배열 요소로 2차원 배열을 가짐
  • 하지만 오히려 코드를 복잡하게 만들 수 있어서, 난 안 끌림
// 3행 4열 2차원배열 2개를 요소로 가짐
int score[2][3][4] = {
	{{72, 80, 95, 60}, {68, 98, 83, 90}, {75, 72, 84, 90}},
	{{66, 85, 90, 88}, {95, 92, 88, 95}, {43, 72, 56, 75}}
};

연습문제

5행 6열의 2차원 배열을 선언하고, 4행 5열 부분은 1부터 20까지 초기화합니다. 초기화한 배열에서 마지막 열의 요소에는 각 행의 합을, 마지막 행의 요소에는 각 열의 합을 저장한 뒤 전체 배열의 값을 출력하세요.

  • int arr[5][6] = {0}으로 모든 값이 0인 5행 6열 배열 초기화
  • 4행 5열 부분 -> arr[i][j]의 값은 5 * i + j + 1
  • arr[i][5]i행, arr[4][j]j열, arr[4][5]에 모든 요소의 값을 더함
#include <stdio.h>

int main(void){
    // 행렬 선언 및 값을 0으로 초기화
    int arr[5][6] = {0};

    // 4행 5열 부분을 1부터 20까지 초기화
    for (int i = 0; i < 4; i++){
        for (int j = 0; j < 5; j++){
            arr[i][j] = 5 * i + j + 1;
            // 마지막 열 요소에 더하기
            arr[i][5] += arr[i][j];
            // 마지막 행 요소에 더하기
            arr[4][j] += arr[i][j];
            // 마지막 행, 마지막 열 요소에 더하기
            arr[4][5] += arr[i][j];
        }
    }

    // 마지막 행, 마지막 열
    for (int i = 0; i < 5; i++){
        for (int j = 0; j < 6; j++){
            printf("%5d", arr[i][j]);
        }
        printf("\n");
    }
}

// [출력]
//   1    2    3    4    5   15
//   6    7    8    9   10   40
//  11   12   13   14   15   65
//  16   17   18   19   20   90
//  34   38   42   46   50  210
profile
뭔가 만드는 걸 좋아하는 개발자 지망생입니다. 프로야구단 LG 트윈스를 응원하고 있습니다.

0개의 댓글