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, ArrayDescription.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단계에 걸쳐 배열을 선언하고 초기화해서 코드를 줄여 나가는 내용을 보여드리겠습니다.
1차원 배열을 선언 및 초기화하는 프로그램
우선, 다음 코드와 같이 선언과 요소 수 생성 따로 초기화 따로 하는 코드를 살펴보겠습니다.
코드: array_one1.c, ArrayOne1.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으로 초기화
이번에는 선언과 동시에 모든 요소를 일단 0으로 초기화하는 코드로 변환해 보겠습니다.
코드: array_one2.c, ArrayOne2.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, ArrayOne3.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, ArrayTotalAvg.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개의 값을 더하여 출력하는 간단한 예제입니다.
11. 배열의 값을 while 문으로 출력하기
while
문을 이용해 배열의 값을 순차적으로 출력하는 방법을 알아보겠습니다. 특히, 배열에서 null
종결 문자('\0'
)를 만날 때까지 반복하면서 각 인덱스에 해당하는 문자를 출력합니다.
배열 문자 출력 예제
코드: array_while.c
// 배열의 값들을 while 문을 사용하여 반복적으로 출력하는 예제
#include <stdio.h>
int main(void)
{
char see[] = "C language\n"; // 문자 배열 선언 및 초기화
int index = 0; // 인덱스 변수 초기화
while (see[index] != '\0') // null 종결 문자를 만날 때까지 반복
{
putchar(see[index]); // 현재 인덱스의 문자 출력
index++; // 인덱스 증가
}
return 0;
}
출력:
C language
이 코드는 C language
문자열이 저장된 문자 배열을 순회하며, 배열 내 각 문자를 while
반복문을 사용해 출력합니다. 반복은 문자열의 끝을 나타내는 null
종결 문자('\0'
)를 만날 때까지 지속됩니다.
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차원 배열의 크기를 구하는 것은 배열이 총 몇 개의 원소를 포함할 수 있는지 알아내는 데 중요합니다. 배열의 크기는 그 배열이 차지하는 메모리의 양을 바이트 단위로 나타낸 것입니다. 이 섹션에서는 C 언어를 사용하여 2차원 배열의 크기를 계산하는 방법을 알아보겠습니다.
2차원 배열 크기 계산 예제
코드 파일: calculate_2d_array_size.c
#include <stdio.h>
int main(void)
{
// 3행 4열의 2차원 정수 배열 선언
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);
printf("배열의 한 원소 크기: %d 바이트\n", element_size);
printf("2차원 배열의 총 원소 개수: %d\n", total_elements);
return 0;
}
출력 결과:
2차원 배열의 총 크기: 48 바이트
배열의 한 원소 크기: 4 바이트
2차원 배열의 총 원소 개수: 12
행과 열의 개수 계산
또한, 2차원 배열의 행과 열의 개수를 계산하는 방법도 알아보겠습니다. 이 방법은 배열이 동적으로 선언되었을 때 유용합니다.
코드: calculate_array_dimensions.c
#include <stdio.h>
int main(void)
{
// 초기화를 통해 크기가 결정되는 2차원 배열 선언
int arr1[][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
int arr2[][6] = { {1, 2, 3, 4, 5, 6}, {7, 8, 9, 10, 11, 12} };
// arr1 배열의 열과 행의 개수 계산
int arr1_col = sizeof(arr1[0]) / sizeof(int);
int arr1_row = sizeof(arr1) / sizeof(arr1[0]);
// arr2 배열의 열과 행의 개수 계산
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
위 예제에서 arr1
과 arr2
배열의 전체 크기, 한 원소의 크기를 구하여 배열의 총 원소 개수를 계산했습니다. 이러한 방식으로 2차원 배열의 크기와 구조를 이해하는 것은 배열을 효율적으로 사용하는 데 중요한 요소입니다.
19. 3차원 배열의 생성
이번 섹션에서는 3차원 배열의 생성 방법을 살펴봅니다. 3차원 배열은 데이터를 층(layer), 행(row), 열(column) 형태로 구조화하여 관리할 수 있게 해주는 고급 데이터 구조입니다. 다음 예제는 프로그래밍 언어 이름을 저장하는 3차원 배열을 만들고 사용하는 방법을 보여줍니다.
3차원 배열 생성 및 활용 예제
코드 파일: array_three_description.c
//[?] 3차원 배열을 통한 데이터 구조화 예제
#include <stdio.h>
int main(void)
{
//[1] 3차원 배열 선언: 총 8개의 문자열 포인터를 저장할 수 있는 구조
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;
}
출력 결과:
0층
C 언어, C++
C#, Java
1층
Python, JavaScript
Kotlin, Go
3차원 배열은 각각의 층에 2차원 배열(행과 열)을 포함하고 있으며, 복잡한 정보를 계층적으로 구조화할 수 있게 합니다. 예제에서 볼 수 있듯이, 3차원 배열을 사용하여 다양한 프로그래밍 언어를 효과적으로 관리할 수 있습니다. 이러한 배열은 비록 일상적으로 자주 사용되는 구조는 아니지만, 특정한 상황에서 데이터를 체계적으로 조직하는 데 매우 유용할 수 있습니다.
20. 3차원 배열의 생성과 출력
이 섹션은 3차원 배열을 생성하고, 이를 출력하는 방법에 대해 다룹니다. 3차원 배열은 보통 층(layer), 행(row), 열(column)으로 이루어져 있으며, 다양한 형태의 복잡한 데이터 구조를 표현하는 데 유용합니다.
3차원 배열의 초기화와 출력 방법
코드 파일: array_three.c
#include <stdio.h>
int main(void)
{
// 2층, 3행, 4열 구조를 가진 3차원 배열 초기화
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 } }
};
// 3중 중첩 for문으로 배열의 모든 요소를 순서대로 출력
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
이 예제는 2층, 3행, 4열 구조를 가진 3차원 배열을 생성하고, 이 배열의 모든 요소를 체계적으로 출력하는 과정을 보여줍니다. 3중 중첩된 for
반복문을 사용하여 각 층, 행, 열의 요소를 순차적으로 탐색하고 출력하며, 이를 통해 3차원 배열의 구조를 이해할 수 있습니다.
3차원 배열의 크기 계산
3차원 배열의 크기를 계산하는 또 다른 예제입니다. 이 코드는 배열의 깊이(depth), 행 수, 열 수를 계산하여 출력합니다.
코드: array_dimension_size.c
#include <stdio.h>
int main(void)
{
// 초기화된 2 * 2 * 4 크기의 3차원 배열
int arr[][2][4] = { {1, 2, 3, 4, 5, 6, 7, 8}, {9, 10, 11, 12, 13, 14, 15, 16} };
// 배열의 차원별 크기 계산
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
이러한 예제들은 3차원 배열을 선언하고 그 구조를 탐색하는 방법, 그리고 배열의 크기를 계산하는 방법을 보여줍니다. 3차원 배열은 다차원 데이터를 표현하거나 복잡한 데이터 구조를 관리할 때 매우 유용합니다.
18.21 예제: 여러 학생의 점수를 배열에 저장하고 총점 계산하기
이 예제에서는 N명의 학생 점수를 입력받아 1차원 배열에 저장한 후, 이를 이용해 총점을 구하는 방법을 보여줍니다. 배열을 활용하여 여러 값들을 효율적으로 관리할 수 있으며, 반복문을 사용해 데이터를 처리하는 과정을 단순화할 수 있습니다.
학생 점수 입력받아 배열에 저장하고 총점 구하기
코드: array_input.c
// 학생들의 점수를 입력받아 배열에 저장한 뒤 총점을 계산하는 프로그램
#define _CRT_SECURE_NO_WARNINGS // 컴파일러 경고 방지
#include <stdio.h>
#define N 3 // 학생 수 정의
int main(void)
{
int array[N]; // N명의 학생 점수를 저장할 배열 선언
int total = 0; // 총점 초기화
// [1] 입력: 각 학생의 점수를 입력받아 배열에 저장
for (int i = 0; i < N; i++)
{
printf("%d번 학생 점수: ", (i + 1));
scanf("%d", &array[i]); // scanf의 반환 값을 사용하지 않으므로 변수 할당 생략
}
// [2] 처리: 배열에 저장된 점수들을 합하여 총점 계산
for (int i = 0; i < N; i++)
{
total += array[i]; // 각 학생 점수를 총점에 더하기
}
// [3] 출력: 계산된 총점 출력
printf("%d명 학생의 총점: %d\n", N, total);
return 0;
}
출력 예시:
1번 학생 점수: 100
2번 학생 점수: 90
3번 학생 점수: 80
3명 학생의 총점: 270
이 프로그램은 먼저 사용자로부터 N명의 학생 점수를 입력받아 배열에 저장합니다. 이후, 저장된 점수들을 순회하며 총점을 계산하고, 마지막으로 계산된 총점을 출력합니다.
18.22 strcpy()
함수를 이용한 문자열 복사
strcpy()
함수를 사용하면 문자 배열에 문자열 리터럴을 저장할 수 있습니다. 이 함수는 <string.h>
헤더 파일에 정의되어 있으며, 문자열을 한 배열에서 다른 배열로 복사하는 데 사용됩니다. 아래 예제에서는 "C Language"
라는 문자열 리터럴을 buffer
배열에 복사하는 방법을 보여줍니다.
문자열 리터럴을 문자 배열에 저장하는 예제
코드: char_array_strcpy.c
// char_array_strcpy.c
#define _CRT_SECURE_NO_WARNINGS // 최신 컴파일러에서 경고 방지
#include <stdio.h>
#include <string.h> // strcpy() 함수 사용을 위해 필요
int main(void)
{
char buffer[80]; // 문자를 저장할 배열 선언
// strcpy() 함수로 "C Language" 문자열 리터럴을 buffer 배열에 복사
strcpy(buffer, "C Language");
// 복사된 문자열 출력
printf("%s\n", buffer); // 출력: "C Language"
return 0;
}
출력:
C Language
이 예제는 strcpy()
함수를 사용하여 "C Language"
문자열을 buffer
배열에 저장하고, 저장된 문자열을 printf()
함수를 사용하여 출력하는 과정을 보여줍니다.
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"
문자열을 출력하는 내용을 코드로 작성했습니다.
정보처리기사 실기 시험 기출 문제 - 문자열 역순 출력
문제
다음 C 프로그램이 실행되었을 때의 동작을 설명하고, 출력 결과를 예측하시오.
소스 코드 파일명: string_reverse.c
#include <stdio.h>
main() {
char str1[5] = "abcd";
char str2[5];
for (int i = 0; i < 4; i++)
str2[i] = str1[3 - i];
str2[4] = '\0';
printf("%s", str2);
}
입력 예시
이 프로그램은 사용자로부터 입력을 받지 않습니다.
출력 예시
dcba
해설
이 프로그램은 문자열 str1
에 저장된 문자들을 역순으로 str2
에 복사한 후, str2
를 출력합니다.
char str1[5] = "abcd";
는 문자열abcd
를 저장하는 문자 배열str1
을 선언하고 초기화합니다.char str2[5];
는 결과를 저장할 문자 배열str2
를 선언합니다.for (int i = 0; i < 4; i++)
루프를 통해str1
의 각 문자를 역순으로str2
에 복사합니다. 이 때,str1[3 - i]
를 사용하여str1
의 마지막 문자부터 순서대로str2
의 첫 번째 인덱스부터 저장합니다.str2[4] = '\0';
는 문자열의 끝을 나타내는 널 문자(\0
)를str2
의 마지막에 추가합니다.printf("%s", str2);
는 역순으로 복사된 문자열str2
를 출력합니다.
이 프로그램은 문자열 처리와 배열을 사용하여 문자열을 역순으로 만드는 방법을 보여줍니다.
정보처리기사 실기 시험 기출 문제 - 2차원 배열의 합계 계산
문제
다음 C 프로그램이 실행되었을 때의 동작을 설명하고, 출력 결과를 예측하시오.
소스 코드 파일명: two_dimensional_array_sum.c
#include <stdio.h>
main() {
int a[3][5] = { {27, 13, 21, 41, 12},
{11, 20, 17, 35, 15},
{21, 15, 32, 14, 10} };
int sum, ssum = 0;
for (int i = 0; i < 3; i++) {
sum = 0;
for (int j = 0; j < 5; j++)
sum += a[i][j];
ssum += sum;
}
printf("%d", ssum);
}
입력 예시
이 프로그램은 사용자로부터 입력을 받지 않습니다.
출력 예시
정답 예시에 해당하는 숫자를 여기에 작성합니다. (계산 필요)
해설
이 프로그램은 3행 5열의 2차원 배열에 저장된 모든 요소의 합을 계산합니다.
int a[3][5] = ...
는 3행 5열의 2차원 배열을 선언하고 초기화합니다. 배열에는 각각의 요소에 정수 값이 할당됩니다.int sum, ssum = 0;
는 각 행의 합(sum
)과 전체 합(ssum
)을 계산하기 위한 변수를 선언하고,ssum
은 0으로 초기화합니다.- 첫 번째
for
루프(for (int i = 0; i < 3; i++)
)는 배열의 각 행을 순회합니다. - 두 번째
for
루프(for (int j = 0; j < 5; j++)
)는 현재 행의 각 열을 순회하며, 해당 요소의 값을sum
에 더합니다. - 각 행의 합계(
sum
)는 전체 합(ssum
)에 더해집니다. - 마지막으로,
printf("%d", ssum);
는 계산된 전체 합을 출력합니다.
이 프로그램은 2차원 배열을 사용하는 방법과 중첩된 반복문을 사용하여 배열 내 모든 요소의 합을 계산하는 방법을 보여줍니다.