18 배열 사용하기
배열(Array)은 동일한 데이터 타입을 갖는 데이터들의 집합체를 의미합니다. 배열을 사용하면 편리하게 데이터들을 모아서 관리할 수 있습니다.
배열을 한 줄 정의하면 다음과 같습니다.
> // 배열(Array): 하나의 이름으로 같은 데이터 타입을 여러 개 보관해 놓는 그릇
> // 배열은 모두 동일한 데이터 형식의 연속된 개체 모음입니다.
18.1 배열(Array)
하나의 이름으로 여러 개의 데이터를 저장하는 데이터 구조를 배열(Array)이라고 합니다. 계속 반복해서 설명되는 내용인데요. 다음 내용은 가볍게 읽고 넘어갑니다.
- 하나의 변수(Variable)에 하나의 값만을 저장할 수 있는 변수와는 달리 배열(Array)에는 하나의 배열명에 여러 개의 데이터를 보관할 수 있습니다. 이처럼 변수 여러 개를 하나의 이름으로 관리하는 것을 배열이라고합니다.
- 배열은 요소들의 순서있는 집합입니다. 각 요소는 인덱스로 접근할 수 있습니다. 인덱스는 0부터 시작합니다.
- 하나의 배열에는 하나의 데이터 타입(정수형 배열, 문자열 배열 등)만을 보관할 수 있습니다.
- 배열은 메모리의 연속된 공간을 미리 할당하고 이를 대괄호([])와 0부터 시작하는 정수형 인덱스를 사용하여 접근하는 구조입니다.
- 배열도 변수입니다.
CAUTION
n - 1(n 마이너스 1) 규칙
배열의 인덱스는 0부터 요소의 개수에서 1을 뺀 수만큼의 범위를 가집니다.
- 5개 요소: 0 ~ 4
- 10개 요소: 0 ~ 9
다음 그림은 변수와 배열을 그림으로 표현해 본 내용입니다.
그림: 변수(Variable)와 배열(Array)
NOTE
배열을 그림으로 표현할 때 0, 1, 2
순서로 번호를 줄 때 그림에서 아래에서 위로 그려도 되고 위에서 아래로 그려도 됩니다. 딱히 구분지을 필요는 없습니다.
요소(Element) 또는 항목(Item)
배열의 하나의 값을 요소 또는 항목으로 표현합니다.
배열 사용의 장점
배열을 사용하게되면 다음과 같은 장점이 있습니다.
- 하나의 이름으로 여러 개의 변수를 묶어서 관리하기에 관리가 편합니다.
- 반복문을 사용하여 쉽게 반복하여 값을 사용할 수 있습니다.
- 정확히 필요한 데이터의 수가 정해지면 메모리를 적게 사용해 프로그램 크기가 작아집니다.
- 읽고 쓰기 작업이 빨라 성능이 향상됩니다.
배열 사용 전
배열을 사용하지 않고 변수를 사용하여 10명의 학생의 국어 점수를 기록하는 일을 진행한다면, 변수를 10개 선언해야 합니다. 하지만, 학생의 수가 20명, 30명으로 늘어날 때마다 매번 변수를 선언할 수는 없는 노릇입니다. 이런 경우에는 배열을 선언하게 되면 하나의 이름으로 20명, 30명의 학생들의 점수를 보관해서 사용할 수 있습니다.
다음 예제 코드는 3명의 학생의 총점을 구하는 내용을 보여줍니다. 이런 방식으로 30명 학생이라면 30개의 변수를 선언해야 합니다. 그래서 배열이 필요한 것입니다.
코드: why_array.c
//[?] 배열을 사용하지 않고 3명의 학생의 국어 점수의 총점을 구하려면?
#include <stdio.h>
int main(void)
{
int kor1 = 90; // 1번 학생
int kor2 = 80; // 2번 학생
int kor3 = 70; // 3번 학생
int tot = kor1 + kor2 + kor3;
printf("총점: %d", tot); // 240
return 0;
}
총점: 240
배열의 이름
C 언어에서의 배열의 이름은 첫 번째 요소의 주소입니다.
char name[25];
scanf("%24s", name);
배열의 이름은 배열의 시작 주소를 나타냅니다.
18.2 배열 선언하기
배열의 선언은 데이터 타입 이름 뒤에 [] 기호를 사용하여 배열을 선언합니다. 배열에 저장된 데이터는 정수형 인덱스(Index)를 통해서 접근 가능합니다. 배열에 있는 데이터를 출력할 때에는 for 문 등을 사용하여 반복하여 출력합니다.
그림: 배열 표기법
예를 들어, 정수형 배열은 다음과 같이 선언할 수 있습니다.
int numbers[5];
위 코드는 정수형 배열을 선언한 후 요소 수를 생성하게 됩니다. 배열의 크기 생성시 사용되는 숫자를 첨자(Subscript)라고 부릅니다. 첨자는 흔히 인덱스라고 합니다.
int intArray[3];
위와 같은 코드에서 intArray의 첨자는 3입니다.
선언된 배열은 0부터 시작하는 인덱스(Index)를 사용하여 접근할 수 있습니다.
intArray[0]
, intArray[1]
, intArray[2]
순서대로 첨자 3으로 선언된 배열은 0, 1, 2의 3개의 인덱스를 가집니다. 우리가 일상 생활에서는 1부터 숫자를 세지만 C 언어에서는 0부터 숫자를 세는 구조입니다. 이러한 규칙을 0 기반(Zero Base) 또는 (n – 1) 규칙이라고도 합니다.
인덱스는 0부터 n-1(전체 요소에서 한개를 뺀)까지 배열의 요소를 반복해서 출력해 주는 용도로 사용됩니다.
배열을 만드는 방법을 한글로 표현하면 다음과 같습니다.
데이터형식 배열이름[크기];
이러한 배열에는 다음과 같은 종류가 있습니다.
- 1차원 배열: 배열의 첨자를 하나만 사용하는 배열
- 다차원 배열: 2개 이상의 첨자를 사용하는 배열(2차원, 3차원, …)
18.3 1차원 배열 선언, 초기화 참조
1차원 배열을 선언하여 메모리 영역의 확보하는 코드는 다음 형태를 가집니다.
데이터 타입 배열명[첨자];
1차원 배열의 요소에 값을 대입하는 코드는 다음과 같습니다.
배열명[인덱스] = 값;
1차원 배열의 참조는 정수형 인덱스를 사용하여 접근할 수 있습니다.
printf(배열명[인덱스]);
1차원 배열 관련 용어에서 인덱스와 첨자는 같은 뜻으로 사용되며, 인덱스를 사용하여 하나의 배열 요소를 가져올 수 있습니다.
- 인덱스 또는 첨자
- 복수의 데이터를 구분 짓는 번호
int intNum[10];
<- 여기서 숫자 10이 인덱스(첨자)
- 요소
- 배열의 요소: 하나의 첨자를 가지는 배열
사원번호[3]
<- 3번 인덱스에 위치한 배열의 요소
C 언어 배열 이니셜라이저 식
C 언어 배열 이니셜라이저 식에 대해 소개합니다.
코드: array_initializer.c
// array_initializer.c
// 배열 이니셜라이저 식
#include <stdio.h>
int main(void)
{
int num = { 1234 }; // 배열 이니셜라이저(초기자, 초기화자)
double numbers[] = { 1234, 3.14 }; // 배열 이니셜라이저
printf("%d\n", num); // 1234
printf("%lf, %lf\n", numbers[0], numbers[1]); // 1234.000000, 3.140000
return 0;
}
1234
1234.000000, 3.140000
18.3.1 1차원 배열 사용 예제
다음과 같이 arr 이름의 배열을 선언하면, 메모리 상에 다음과 같이 5개의 공간이 잡힙니다.
int arr[5];
인덱스가 5이므로 C 언어에서의 배열의 첨자는 0부터 시작해서 선언할 때의 첨자인 (5 - 1)까지의 5개가 만들어집니다. C 언어에서는 n - 1 규칙 또는 0 베이스(Zero Base) 또는 제로 오프셋(Zero Offset)이라고 해서 모든 배열과 같은 데이터 구조의 인덱스는 0번째부터 사용됨을 기억하기 바랍니다.
18.4 1차원 배열 만들기
자, 처음으로 1차원 배열을 만들어 보도록 하겠습니다. 하나의 이름인 numbers
로 2개의 정수를 저장하는 예제입니다.
코드: array_description.c
//[?] 1차원 배열 만들기
#include <stdio.h>
int main(void)
{
//[1] 배열 선언: 크기가 2인 배열 선언
int numbers[2];
//[2] 배열 초기화
numbers[0] = 3840;
numbers[1] = 2160;
//[3] 배열 사용
printf("%d * %d\n", numbers[0], numbers[1]);
return 0;
}
3840 * 2160
정수형 배열인 numbers
를 생성한 후 2개의 요소를 할당합니다. 요소수를 2로 선언했으므로 [0]
, [1]
의 2개의 요소가 생성됩니다. 각각의 요소에는 [0]
, [1]
형태의 인덱스를 통해서 값을 할당할 수 있습니다. 배열의 값은 numbers[n]
형태로 가져와 사용할 수 있습니다.
18.5 배열 선언과 동시에 초기화해서 코드 줄이기
지금부터는 3단계에 걸쳐 배열을 선언하고 초기화해서 코드를 줄여 나가는 내용을 보여드리겠습니다. 우선, 다음 코드와 같이 선언과 요소 수 생성 따로 초기화 따로 하는 코드를 살펴보겠습니다.
코드: array_one1.c
//[?] 1차원 배열을 선언 및 초기화하는 프로그램
#include <stdio.h>
int main(void)
{
//[1] 1차원 배열 선언
int intArray[3];
//[2] 배열 초기화
intArray[0] = 1;
intArray[1] = 2;
intArray[2] = 3;
//[3] for 문 사용 출력
for (int i = 0; i < 3; i++)
{
printf("%d번째 인덱스: %d\n", i, intArray[i]);
}
return 0;
}
0번째 인덱스: 1
1번째 인덱스: 2
2번째 인덱스: 3
이번에는 선언과 동시에 모든 요소를 일단 0으로 초기화하는 코드로 변환해 보겠습니다.
코드: array_one2.c
//[?] 배열의 모든 요소를 0으로 초기화
#include <stdio.h>
int main(void)
{
//[1] 1차원 배열 선언과 동시에 0으로 초기화
int intArray[3] = { 0, };
//[2] 배열 초기화
intArray[0] = 10;
intArray[1] = 20;
intArray[2] = 30;
//[3] for 문 사용 출력
for (int i = 0; i < 3; i++)
{
printf("%d번째 인덱스: %d\n", i, intArray[i]);
}
return 0;
}
0번째 인덱스: 10
1번째 인덱스: 20
2번째 인덱스: 30
배열 선언 시 바로 요소 생성 및 초기화할 수 있습니다.
코드: array_one3.c
//[?] 배열을 선언과 동시에 초기화
#include <stdio.h>
int main(void)
{
//[!] 1차원 배열 선언과 동시에 원하는 값으로 초기화
int intArray[3] = { 100, 200, 300 };
for (int i = 0; i < 3; i++)
{
printf("%d번째 인덱스: %d\n", i, intArray[i]);
}
return 0;
}
0번째 인덱스: 100
1번째 인덱스: 200
2번째 인덱스: 300
3단계를 거쳐서 1차원 배열을 선언하고 요소의 값을 초기화하고 이를 출력하는 내용을 살펴보았습니다.
18.6 배열의 나머지 요소를 0으로 초기화
배열의 요소를 초기화할 때 따로 값을 지정하지 않으면 0으로 초기화됩니다.
코드: array_init.c
#include <stdio.h>
int main(void)
{
//[1] 모두 초기화
int all[5] = { 1, 2, 3, 4, 5 };
//[2] 나머지 0으로 초기화
int zero[5] = { 1, 2, /* 나머지 요소 0으로 초기화 */ };
for (int i = 0; i < 5; i++)
{
printf("%d\t", all[i]);
}
printf("\n");
for (int i = 0; i < 5; i++)
{
printf("%d\t", zero[i]);
}
printf("\n");
return 0;
}
1 2 3 4 5
1 2 0 0 0
18.7 문자 배열을 puts() 함수로 출력하기
문자 여러 개를 배열에 저장 후 puts() 함수로 출력하는 예제를 살펴보겠습니다.
코드: character_array.c
#include <stdio.h>
int main(void)
{
char characters[] = { 'a', 'b', 'c', 'd', '\0' }; // 문자 배열
puts(characters); // null 종결 문자를 포함한 문자 배열 출력
return 0;
}
abcd
널 종결 문자를 마지막에 포함한 문자 배열은 puts() 함수로 출력이 가능합니다.
18.8 배열 인덱스에 증감 연산자 사용하기
배열의 인덱스는 정수형이기에 다음 코드와 같이 증감 연산자와 함께 사용도 가능합니다. 여기서 주의할 점은 인덱스가 정해진 크기를 벗어나면 에러가 발생됩니다.
코드: array_index.c
// 배열 인덱스에 증감 연산자 사용하기
#include <stdio.h>
int main(void)
{
// array 이름으로 1차원 배열 선언과 동시에 1, 2, 3으로 값 초기화
int array[] = { 1, 2, 3 };
int index = 0; // 배열의 인덱스는 0부터 시작하기에 0으로 index 변수 초기화
printf("%d\t", array[index++]); // array[0] 출력 후, index == 1로 증가
printf("%d\t", array[index++]); // array[1] 출력 후, index == 2로 증가
printf("%d\n", array[index++]); // array[2] 출력 후, index == 3로 증가
printf("%d\t", array[--index]); // index == 2로 감소 후, array[2] 출력
printf("%d\t", array[--index]); // index == 1로 감소 후, array[1] 출력
printf("%d\n", array[--index]); // index == 0로 감소 후, array[0] 출력
return 0;
}
1 2 3
3 2 1
배열의 인덱스를 지정하는 [] 영역에는 정수형 값이 필요합니다. 이 정수형 값을 표현할 때에는 ++, --와 같은 증감 연산자를 함께 사용할 수 있습니다.
18.9. 배열을 사용하여 국어 점수의 총점과 평균 구하기
이번에는 배열을 사용하여 국어 점수의 총점과 평균을 구하는 프로그램을 만들어보겠습니다. 만약, 배열을 사용하지 않는다면 3명의 학생의 점수를 저장하는 변수를 3개 선언해야 합니다. 50명의 학생이라면 50개의 변수를 선언해야합니다. 배열을 사용하면 여러 개의 데이터를 처리할 때 편리하게 사용할 수 있습니다.
Visual Studio에서 다음 코드를 작성 후 실행해보세요.
코드: array_total_avg.c, 배열_합계평균.c
#include <stdio.h>
int main(void)
{
int kor[3];
int sum = 0; // 합계가 담길 변수 sum 선언과 동시에 0으로 초기화
float avg = 0; // 평균이 담길 실수형 변수 avg 선언과 동시에 0으로 초기화
// 배열에 수작업으로 직접 값 대입
kor[0] = 100;
kor[1] = 90;
kor[2] = 80;
sum = kor[0] + kor[1] + kor[2]; // 총점 계산
avg = sum / (float)3.0; // 평균 계산
// 총점과 평균 출력: 평균은 소수점 2자리까지 출력
printf("총점: %d, 평균: %.2f\n", sum, avg);
return 0;
}
총점: 270, 평균: 90.00
총점을 구하는 부분을 수작업으로 진행했지만, 반복문을 사용해서 합계를 구하면 훨씬 편합니다.
실수 데이터는 %.2f
모양의 서식 지정자를 사용하여 소수점 2자리까지 표현했습니다.
18.10 gets_s()와 atoi()로 값 입력 받아 배열에 저장한 후 출력
이번에는 gets_s() 함수와 atoi() 함수로 사용자로부터 입력된 값을 배열에 저장한 후 출력해보도록 하겠습니다.
코드: array_student.c
// 3명의 학생의 점수를 입력받아 총점을 구하는 프로그램
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
// 3개의 요소를 가지는 1차원 배열 생성
int students[3];
char buffer[5];
int total = 0;
// 사용자로부터 정수 데이터 3개 입력받아 배열에 저장
for (int i = 0; i < 3; i++)
{
printf("%d번 학생 점수: ___\b\b\b", (i + 1));
gets_s(buffer, sizeof(buffer)); // 사용자부터 점수 입력
students[i] = atoi(buffer); // 입력된 값을 정수로 변환
total += students[i];
}
// 출력하기
printf("\n점수: ");
for (int i = 0; i < 3; i++)
{
printf("%d\t", students[i]);
}
printf("\n총점: %d\n", total);
return 0;
}
1번 학생 점수: 100
2번 학생 점수: 90_
3번 학생 점수: 80_
점수: 100 90 80
총점: 270
콘솔로부터 입력된 정수를 3개의 배열 요소로 받은 후 3개의 값을 더하여 출력하는 간단한 예제입니다.
18.11 배열의 값을 while 문으로 반복해서 출력하기
while 문을 사용하여 배열의 인덱스를 반복하면서 출력할 수 있습니다. 이 때 null 종결 문자를 만날 때까지 반복합니다.
코드: array_while.c
// 배열의 값을 while 문으로 반복해서 출력하기
#include <stdio.h>
int main(void)
{
char see[] = "C language\n";
int index = 0;
while (see[index] != '\0')
{
putchar(see[index]);
index++;
}
return 0;
}
C language
18.12 다차원 배열
2차원 배열 및 3차원 배열과 같이 차원이 2 이상인 배열을 다차원 배열이라고 합니다. 다차원 배열은 다음과 같이 선언합니다.
데이터형식 배열이름[2][3]; // 2차원 배열을 선언합니다.
데이터형식 배열이름[2][3][4]; // 3차원 배열을 선언합니다.
2행 3열 배열을 선언하면 다음 그림과 같습니다.
int arr[2, 3];
그림: 2차원 배열의 인덱스
1차원, 2차원, 3차원 배열을 선언하는 방법은 다음과 같습니다.
C 언어에서 배열을 선언할 때에는 대괄호 기호 쌍인 []를 기준으로 차원을 구분합니다.
// 배열 선언
int oneArray[]; // 1차원 배열 선언
int twoArray[][]; // 2차원 배열 선언
int threeArray[][][]; // 3차원 배열 선언
예를 들어, 2차원 배열 초기화는 다음과 같습니다.
int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
2차원 배열의 선언
C 언어에서 2차원 배열을 선언하는 방법은 다음과 같습니다:
dataType arrayName[rowSize][columnSize];
dataType
: 배열이 저장할 데이터의 타입입니다. 예를 들어,int
,float
,char
등이 될 수 있습니다.arrayName
: 배열의 이름입니다.rowSize
와columnSize
: 배열의 행(세로) 크기와 열(가로) 크기를 나타냅니다.
예를 들어, 3행 4열의 정수 배열을 선언하려면 다음과 같이 작성할 수 있습니다:
int arr[3][4];
또한, 2차원 배열의 원소에 접근하려면 배열 이름과 함께 2개의 인덱스를 사용합니다. 예를 들어, arr[2][3]
은 3x4 크기의 2차원 배열에서 2번째 행 3번째 열에 해당하는 원소를 가리킵니다.
2차원 배열의 초기화
2차원 배열은 선언과 동시에 초기화할 수 있습니다. 예를 들어, 2행 3열의 배열을 생성하고 초기화하려면 다음과 같이 작성할 수 있습니다:
int arr[2][3] = { {1, 2, 3}, {4, 5, 6} };
이 코드는 첫 번째 행에는 1, 2, 3을, 두 번째 행에는 4, 5, 6을 저장합니다.
2차원 배열의 접근
2차원 배열의 각 요소에 접근하는 방법은 간단합니다. 배열 이름과 인덱스를 이용하면 됩니다. 예를 들어, 다음 코드는 arr 배열의 두 번째 행의 세 번째 요소를 출력합니다:
printf("%d", arr[1][2]); // 출력: 6
이차원 배열 만들기
이번에는 2차원 배열을 선언하고 각각의 데이터를 초기화한 후 이를 사용하는 예제를 만들어보겠습니다.
코드: array_two_description.c
//[?] 2차원 배열: 행과 열로 이루어진 배열
#include <stdio.h>
int main(void)
{
//[1] 2차원 배열 선언
char arr[2][2];
//[2] 2차원 배열 초기화
arr[0][0] = 'A';
arr[0][1] = 'B';
arr[1][0] = 'C';
arr[1][1] = 'D';
//[3] 2차원 배열 사용
printf("%c, %c\n", arr[0][0], arr[0][1]);
printf("%c, %c\n", arr[1][0], arr[1][1]);
return 0;
}
A, B
C, D
2차원 배열은 표 형태로 데이터를 관리하고자할 때 유용합니다.
이차원 배열 생성 및 반복문으로 출력하기
2차원 배열을 생성한 후 값을 대입 후 이를 for
문을 사용하여 출력하는 예제를 만들어보겠습니다. 반복을 여러 번 하는 복잡한 예제이므로 부록의 디버거 사용하기를 참고하여 **F10
**을 여러 번 눌러가면서 단계별로 코드를 실행해보면 좋습니다.
코드: array_two1.c
//[?] 이차원 배열 생성 및 반복문으로 출력하기
#include <stdio.h>
int main(void)
{
// 2차원 배열 선언
int intArray[2][3];
// 2차원 배열 초기화
intArray[0][0] = 1;
intArray[0][1] = 2;
intArray[0][2] = 3;
intArray[1][0] = 4;
intArray[1][1] = 5;
intArray[1][2] = 6;
// 2중 for 문으로 2차원 배열 출력
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d\t", intArray[i][j]);
}
printf("\n"); // 행 출력 후 줄바꿈
}
return 0;
}
1 2 3
4 5 6
이차원 배열의 내용을 출력할 때에는 두개의 for
문을 사용하여 반복해서 접근해서 사용합니다.
이차원 배열 선언과 동시에 초기화
이번에는 이차원 배열을 선언과 동시에 초기화하는 예제를 살펴보겠습니다.
코드: array_two2.c
//[?] 이차원 배열 선언과 동시에 초기화
#include <stdio.h>
int main(void)
{
// 2차원 배열 선언과 동시에 초기화
int intArray[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
// 2중 for 문으로 2차원 배열 출력
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d\t", intArray[i][j]);
}
printf("\n"); // 행 출력 후 줄바꿈
}
return 0;
}
1 2 3
4 5 6
2차원 배열 선언과 동시에 초기화할 때에는 중괄호가 행의 개수에 맞게 더 추가되는 모양입니다.
2차원 배열을 2개의 for 문으로 출력하기
2차원 배열의 요소를 초기화하는 것은 우리는 이중 중괄호를 사용하여 초기화한 후 2중 for문을 사용하여 출력하는 구조입니다.
코드: array_two_for.c
// 2차원 배열을 2중 for 문으로 반복해서 출력하기
#include <stdio.h>
int main(void)
{
int i, j;
int arr[2][3] = { 1, 2, 3, 4, 5, 6 }; // 안 쪽 중괄호 생략 가능
for (i = 0; i < 2; i++)
{
for (j = 0; j < 3; j++)
{
printf("arr[%d][%d] = %d\n", i, j, arr[i][j]);
}
}
return 0;
}
arr[0][0] = 1
arr[0][1] = 2
arr[0][2] = 3
arr[1][0] = 4
arr[1][1] = 5
arr[1][2] = 6
위 예제와 같은 2중 for문을 사용하는 내용은 알고리즘을 학습하는 샘플 소스에서 굉장히 많이 볼 수 있는 구조입니다. 귀찮더라도 부록의 디버거 사용하기를 참고하여 여러 번 [F10]을 눌러 단계별로 코드가 실행되는 순서를 익혀두기 바랍니다.
3행 3열짜리 2차원 배열에 행과 열이 같으면 1, 다르면 0을 입력한 후 출력하기
3행 3열짜리 배열을 만들고 행과 열이 같은 배열의 위치에 1을 입력한 후 출력하는 내용을 다루어보겠습니다.
코드: array_same_index.c
//[?] 3행 3열짜리 2차원 배열에 행과 열이 같으면 1, 다르면 0을 입력한 후 출력하기
#include <stdio.h>
int main(void)
{
int arr[3][3]; // 3행 3열 정수 배열 선언
for (int i = 0; i < 3; i++) // 행 반복
{
for (int j = 0; j < 3; j++) // 열 반복
{
if (i == j)
{
arr[i][j] = 1; // 행과 열이 같으면 1로 채우기
}
else
{
arr[i][j] = 0; // 행과 열이 다르면 0으로 채우기
}
printf("%d", arr[i][j]);
}
printf("\n");
}
return 0;
}
100
010
001
2차원 배열을 출력할 때 for문과 if 문의 조합으로 인덱스가 같으면 1을 저장하고 다르면 0으로 저장하여 출력하는 예제를 만들어 보았습니다.
이차원 배열을 사용하여 합계와 평균 구하기
다음 그림과 같이 3명의 학생의 국어와 영어 점수의 합계와 평균을 구하는 내용을 2차원 배열을 사용해서 표현해 보겠습니다.
그림: 합계와 평균 구하기
코드: array_sum_average.c
#include <stdio.h>
int main(void)
{
int scores[3][4] =
{
{ 90, 100, 0, 0 },
{ 80, 90, 0, 0 },
{ 100, 80, 0, 0 }
};
for (int i = 0; i < 3; i++)
{
scores[i][2] = scores[i][0] + scores[i][1]; // SUM
scores[i][3] = scores[i][2] / 2; // AVERAGE
}
printf("국어 영어 합계 평균\n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%4d ", scores[i][j]);
}
printf("\n");
}
return 0;
}
국어 영어 합계 평균
90 100 190 95
80 90 170 85
100 80 180 90
2차원 배열은 일반적으로 테이블 형태의 데이터를 다루기에 현업에서 가장 많이 사용되는 구조입니다.
2차원 배열의 크기 구하기
2차원 배열의 크기는 행과 열의 개수를 곱한 결과로 얻을 수 있습니다. 이는 2차원 배열이 총 몇 개의 원소를 가질 수 있는지를 알려줍니다. 이번에는 C 언어에서 2차원 배열의 크기를 구하는 방법을 살펴보겠습니다.
코드: calculate_2d_array_size.c
#include <stdio.h>
int main(void)
{
int arr[3][4];
int total_size = sizeof(arr);
int element_size = sizeof(arr[0][0]);
int total_elements = total_size / element_size;
printf("2차원 배열의 총 크기: %d 바이트\n", total_size); // 48
printf("배열의 한 원소 크기: %d 바이트\n", element_size); // 4
printf("2차원 배열의 총 원소 개수: %d\n", total_elements); // 12
return 0;
}
2차원 배열의 총 크기: 48 바이트
배열의 한 원소 크기: 4 바이트
2차원 배열의 총 원소 개수: 12
위의 코드는 3행 4열의 2차원 배열 arr
을 선언하고 있습니다. 이 배열의 각 요소는 정수이므로 각 요소의 크기는 4 바이트입니다.
sizeof(arr)
는 배열 arr
의 전체 크기(바이트 단위)를 반환하며, sizeof(arr[0][0])
는 배열 arr
의 한 원소(정수형)의 크기를 반환합니다.
따라서 배열 arr
의 총 원소 개수는 전체 배열 크기를 한 원소의 크기로 나눈 결과, 즉 total_size / element_size
를 통해 얻을 수 있습니다.
출력 결과에서 볼 수 있듯이, arr
배열은 총 12개의 정수를 저장할 수 있으며, 이는 행의 개수(3)와 열의 개수(4)를 곱한 결과와 일치합니다.
#include <stdio.h>
int main(void)
{
int arr1[][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; // 3 * 4
int arr2[][6] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; // 2 * 6
int arr1_col = sizeof(arr1[0]) / sizeof(int);
int arr1_row = sizeof(arr1) / sizeof(arr1[0]);
int arr2_col = sizeof(arr2[0]) / sizeof(int);
int arr2_row = sizeof(arr2) / sizeof(arr2[0]);
printf("arr1 열 수: %d\n", arr1_col);
printf("arr1 행 수: %d\n", arr1_row);
printf("arr2 열 수: %d\n", arr2_col);
printf("arr2 행 수: %d\n", arr2_row);
return 0;
}
arr1 열 수: 4
arr1 행 수: 3
arr2 열 수: 6
arr2 행 수: 2
18.19 삼차원 배열 만들기
3차원 배열을 만들어 보겠습니다.
코드: array_three_description.c
//[?] 3차원 배열(층, 행, 열)
#include <stdio.h>
int main(void)
{
//[1] 3차원 배열 선언
char* names[2][2][2]; // 2*2*2=8
//[2] 3차원 배열 초기화
names[0][0][0] = "C 언어";
names[0][0][1] = "C++";
names[0][1][0] = "C#";
names[0][1][1] = "Java";
names[1][0][0] = "Python";
names[1][0][1] = "JavaScript";
names[1][1][0] = "Kotlin";
names[1][1][1] = "Go";
//[3] 3차원 배열 사용
printf("0층\n");
printf("%20s, %20s\n", names[0][0][0], names[0][0][1]);
printf("%20s, %20s\n", names[0][1][0], names[0][1][1]);
printf("\n1층\n");
printf("%20s, %20s\n", names[1][0][0], names[1][0][1]);
printf("%20s, %20s\n", names[1][1][0], names[1][1][1]);
return 0;
}
```output
0층
C 언어, C++
C#, Java
1층
Python, JavaScript
Kotlin, Go
3차원 배열은 행과 열로 이루어진 2차원 배열을 층으로 쌓아서 관리하는 형태의 데이터 구조를 다룰 때 사용됩니다. 3개의 인덱스를 사용하기에 꽤 복잡하지만, 평상시에는 많이 사용되지 않는 데이터 구조이기에 예제로만 살펴보면 됩니다.
18.20 3차원 배열 만들고 3개의 for 문으로 출력하기
이번에는 삼차원 배열을 반복문으로 출력해 보겠습니다.
코드: array_three.c
#include <stdio.h>
int main(void)
{
int intArray[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 } }
};
for (int i = 0; i < 2; i++) // 층 반복
{
for (int j = 0; j < 3; j++) // 행 반복
{
for (int k = 0; k < 4; k++) // 열 반복
{
printf("%2d ", intArray[i][j][k]);
}
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
[][][] 형태로 3차원 배열을 선언하고 의미상으로 층, 행, 열로 이루어진 데이터 구조를 저장할 수 있습니다. 3차원 배열은 3개의 for 문을 사용하여 각 차원을 구분해서 출력합니다. 3차원 배열은 개발 학습 환경에서는 사용 빈도가 적으니 위 예제 정도만 실행해보는 정도로 넘어갑니다.
#include <stdio.h>
int main(void)
{
int arr[][2][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16 }; // 2 * 2 * 4
int depth = sizeof(arr) / sizeof(arr[0]);
int row = sizeof(arr[0]) / sizeof(arr[0][0]);
int col = sizeof(arr[0][0]) / sizeof(int);
printf("arr 깊이: %d\n", depth);
printf("arr 행 수: %d\n", row);
printf("arr 열 수: %d\n", col);
return 0;
}
arr 깊이: 2
arr 행 수: 2
arr 열 수: 4
18.21 예제: N명의 학생의 점수를 입력받아 1차원 배열에 저장 후 총점 구하기
코드: array_input.c
// N명의 학생의 점수를 입력받아 1차원 배열에 저장 후 총점 구하기
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define N 3
int main(void)
{
int array[N]; // N개의 데이터를 갖는 1차원 배열 선언
int tot = 0; // 총점
int _ = 0; // 버림(Discards)
//[1] 입력
for (int i = 0; i < N; i++)
{
printf("%d번 점수: ", (i + 1)); _ = scanf("%d", &array[i]);
}
//[2] 처리
for (int i = 0; i < N; i++)
{
tot += array[i]; // 총점 구하기
}
//[3] 출력
printf("%d명의 총점: %d\n", N, tot);
return 0;
}
1번 점수: 100
2번 점수: 90
3번 점수: 80
3명의 총점: 270
18.22 strcpy() 함수로 문자 배열에 문자열 리터럴 저장하기
코드: char_array_strcpy.c
// char_array_strcpy.c***
```c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h> // strcpy 사용을 위한 헤더 파일
int main(void)
{
char buffer[80];
// strcpy() 함수로 문자열 리터럴을 문자 배열에 저장
strcpy(buffer, "C Language");
printf("%s\n", buffer); // "C Language"
return 0;
}
C Language
18.23 장 요약
하나의 이름으로 여러 개의 데이터를 저장해 놓는 컬렉션(Collection) 구조인 배열(Array)에 대해 알아보았습니다. C 언어에서 배열 데이터 타입은 매우 중요한 역할을 합니다. 잠시 함수를 알아보고 계속해서 C 언어의 여러 데이터 구조를 학습해 나가도록 하겠습니다.
퀴즈: 문자 배열의 내용 바꾸기
문자 배열을 선언과 동시에 문자열로 초기화한 후 특정 인덱스에 있는 문자 배열의 내용을 바꾸는 예제입니다.
코드: char_array_quiz.c
#include <stdio.h>
int main(void)
{
char kitty[] = "c@t";
kitty[1] = 'a'; // 반드시 문자 'a' 할당
printf("%s\n", kitty); // cat
return 0;
}
cat
처음에 "c@t"
문자열로 초기화된 kitty
배열의 1
번째 인덱스의 문자를 'a'
로 변경하여 최종 "cat"
문자열을 출력하는 내용을 코드로 작성했습니다.