이번 글에선 C언어에서 사용하는 배열에 대해서 알아보도록 하겠습니다.
배열이란 무엇일까?
먼저 배열이란 특정한 자료형을 연속적으로 나열하는것을 이야기합니다.
여러분이 만약 숫자 5개를 저장하기위한 int형 변수를 선언하려면 어떻게 해야 할까요?
#include<stdio.h>
int main() {
int num1, num2, num3, num4, num5;
return 0;
}
겨우 변수 5개 이기 때문에 별로 어렵지는 않습니다. 하지만 이것이 숫자 500개라면 어떻게 할까요?
그런 때조차 이렇게 코드를 작성해야 한다면 굉장히 불편하고 귀찮을 것입니다.
이런 코드를 배열을 사용해 코딩하면 매우 쉽게 할 수 있습니다.
먼저 배열의 기본적인 선언 방법부터 알아보도록 하겠습니다.
자료형 배열명[배열크기];
위와 같이 사용하면 지정한 자료형과 배열 크기를 가진 배열을 생성해 이름을 배열명으로 붙입니다.
그러면 이 배열을 통해서 위의 코드와 동일한 동작을 하도록 만들어보겠습니다.
#include<stdio.h>
int main() {
int num[5];
return 0;
}
아주 간단하지 않나요? 여러분이 저장할 숫자가 몇 개가 되든 배열의 크기만 변경해주면 됩니다.
메모리 상에서의 배열
그러면 배열에 대해서 좀 더 자세하게 알아보도록 합시다.
일단 배열을 생성하면 메모리에 배열의 크기만큼 메모리에서 기억공간을 할당받게 됩니다.
각각의 블록들은 변수처럼 사용할 수 있지만, 각각 이름이 정해져 있진 않고, 배열 요소라고 부릅니다.
그저 이러한 여러 개의 기억공간들을 묶어서 하나의 배열명으로 이름을 지정한 것뿐입니다.
각 요소에 접근하기 위해선 배열명과 그 요소의 위치가 필요합니다. 이 위치를 인덱스라고 합니다.
주의할 점은, 인덱스는 0부터 시작해 1씩 증가하고, 0을 포함한 양의 정수만 가질 수 있습니다.
예를 들어 위에서 선언한 num배열 요소들의 인덱스는 각각 0, 1, 2, 3, 4이며,
배열의 첫 번째 값에 접근하려면 num[0]과같이 사용하면 됩니다.
#include<stdio.h>
int main() {
int num[5];
num[0] = 1;
printf("%d", num[0]);
return 0;
}
그렇다면 이러한 배열에 값을 넣는 방법과 이 값을 직접 사용하는 방법에 대해 알아보겠습니다.
먼저 값을 넣는 방법은 최초에 배열을 선언할 때 넣어주는 방법이 있는데, 다음과 같습니다.
#include<stdio.h>
int main() {
int num[5] = { 0, 1, 2, 3, 4 }; //배열의 첫번째 요소부터 순서대로 입력
int num[5] = { 0, 1, 2 }; //위와동일하지만 4번째와 5번째값은 0으로 초기화
int num[5] = { 0 }; //배열의 모든 요소를 0으로 초기화
int num[] = { 0, 1, 2, 3 }; //작성한 값과 동일한 크기의 배열을 생성하고 할당
return 0;
}
주의해야 할 점은 일단 배열을 선언한 뒤에는 위와 같이 값을 초기화할 수 없습니다.
#include<stdio.h>
int main() {
int num[5];
num = { 0, 1, 2, 3, 4 }; //에러발생
return 0;
}
그다음은 배열의 인덱스를 통해 각 요소에 접근해서 직접 값을 초기화하는 방법이 있습니다.
#include<stdio.h>
int main() {
int num[5];
num[0] = 0, num[1] = 1, num[2] = 2, num[3] = 3, num[4] = 4;
return 0;
}
하지만 이렇게 하면 배열을 사용 안 할 때와 비교해 편하기는커녕 더 불편하지 않나요?
반복문을 사용한 배열 출력
따라서 다음과 같이 반복문을 이용해 배열의 요소들에 값을 입력해줍니다.
#include<stdio.h>
int main() {
int i;
int num[5];
for (i = 0; i < sizeof(num) / sizeof(int); i++) {
num[i] = i;
printf("%d ", num[i]);
}
return 0;
}
위의 코드에서 for문의 조건식 부분은 배열의 요소의 개수를 구하는 과정입니다.
sizeof는 전달 인자의 크기가 몇인지 바이트 단위로 알려줍니다.
따라서 sizeof(num)은 배열이 차지하고 있는 메모리 공간의 총크기를 반환하고,
이를 배열의 자료형인 int의 크기(sizeof(int))로 나누어서 배열 요소의 개수를 구할 수 있습니다.
위의 배열은 int형에 크기 5의 배열이니 메모리 공간을 총 20byte만큼 차지하고 있고,
이를 int의 크기인 4로 나누어서 요소의 개수인 5를 구할 수 있는 것이지요.
실제로 코드를 작성할 때는 이 값을 따로 변수로 저장해 두고 사용하시는 걸 추천합니다.
int num_Arr_Size = sizeof(num) / sizeof(int)
이제 배열을 선언하는 법, 값을 입력하는 법, 값을 사용하는 법까지 알아봤으니 직접 코드를 작성해봅시다.
#include<stdio.h>
int main() {
int i;
int age[5];
int sum = 0;
float avr = 0;
int age_Arr_Size = sizeof(age) / sizeof(int);
printf("5명의 나이를 입력하세요 : ");
for (i = 0; i < age_Arr_Size; i++) {
scanf("%d", &age[i]);
sum += age[i];
}
avr = 1.0 * sum / age_Arr_Size;
printf("5명의 나이 : ");
for (i = 0; i < age_Arr_Size; i++) {
printf(", %d살", age[i]);
}
printf("\n5명의 나이의 합 : %d살\n", sum);
printf("5명의 나이의 평균 : %.2f살\n", avr);
return 0;
}
위의 코드는 5명의 나이를 입력받아 각각을 출력하고, 나이의 총합, 평균을 계산, 출력하는 코드입니다.
코드 자체는 그리 어렵지 않으니 쭉 훑어보시면 이해할 수 있을 거라 생각됩니다.
한 가지 말씀드리고 싶은 부분은 avr를 구하는 부분에서 1.0을 곱한 부분인데요,
이는 명시적 형 변환을 사용하는것이 아니라 1.0을 곱함으로써,
암시적 형변환을 통해 avr값이 정상적으로 계산될 수 있도록 한 것입니다.
다차원 배열
지금까지 배열에 대해서 설명해 보았는데요, 사실 위에서 알아본 배열은 1차원 배열이라고 부릅니다.
메모리에 공간이 선형, 즉 1차원으로 잡혀있기 때문에 이처럼 부르는 것인데요,
이를 2차원, 3차원 등등 다차원 배열로 확장시켜 사용할 수 있습니다.
실제 메모리상에서는 그저 연속적인 공간일 뿐입니다만, 편의상 그렇게 부르는 것입니다.
이러한 다차원 배열은 자신보다 한 차원 아래의 배열을 각각의 요소로 가지는 배열입니다.
2차원 배열은 1차원 배열을 각각의 요소로 가지고, 3차원은 2차원을 각각의 요소로 가집니다.
예를 들어 2차원 배열의 형태를 그림으로 보여드리면 다음과 같습니다.
위의 그림은 5개의 요소를 가진 1차원 배열 4개를 요소로 가지는 2차원 배열입니다.
실제 메모리상에선 저 공간들이 1차원적인 연속된 공간이라고 생각하시면 될 것 같습니다.
편의상 2차원 배열에선 1차원을 행, 2차원을 열이라고 부릅니다.
이런 다차원 배열의 선언 방법은 다음과 같습니다.
int num[2][1]; //2*1 2차원배열
int num[3][2][1]; //3*2*1 3차원배열
.
.
.
int num[n][n-1][n-2]...[1] //n*n-1*n-2*...*1 n차원배열
위와 같이 선언하여 자신이 원하는 크기의 다차원 배열을 선언할 수 있습니다.
이번엔 다차원 배열에 값을 넣고 사용하는 방법에 대해서 알아보겠는데, 1차원과 별로 다를 건 없습니다.
먼저 선언 시 초기화 방법입니다.
int num[2][3] = { {1, 2, 3}, {1, 2, 3} }; //2*3 2차원 배열
int num[2][3] = { {1, 2, 3}, {0}};
int num[2][3] = { 0 };
각각 사용법이 1차원 배열과 동일하기 때문에 설명은 생략하도록 하겠습니다.
다음은 배열의 각 요소에 접근하는 법입니다.
int num[4][5] = { 0 };
int num[3][4] = 3;
이는 먼저 4*5크기의 2차원 배열을 선언하고 모든 값을 0으로 초기합니다.
그 후 2차원 배열의 4번째 요소인 1차원 배열의 5번째 요소의 값을 3으로 바꾸는 것입니다.
그림으로 표현하면 더 알기 쉬울 거라고 생각됩니다.
이 또한 기본적인 방법은 1차원 배열과 동일하기 때문에 어렵지 않을 거라고 생각됩니다.
이 정도 설명으로 다차원 배열에 대해서 이해하셨으면 좋을 것 같습니다.
이제 배열에 대한 설명은 충분히 했다고 생각되기 때문에 코드를 작성해보고 마치도록 하겠습니다.
#include<stdio.h>
int main() {
int i, j;
int gugu[9][9];
int gugu_Arr_Size_1D = sizeof(gugu[0]) / sizeof(int); //gugu배열 1차원 요소의 개수
int gugu_Arr_Size_2D = sizeof(gugu) / sizeof(gugu[0]); //gugu배열 2차원 요소의 개수
for (i = 0; i < gugu_Arr_Size_2D; i++) {
for (j = 0; j < gugu_Arr_Size_1D; j++) {
gugu[j][i] = (j+1) * (i+1);
printf("%d * %d = %2d | ", j+1, i+1, gugu[j][i]);
}
printf("\n");
}
}
위의 코드 자체는 이전에 했던 구구단 코드와 구조 자체는 동일합니다.
구구단의 값을 배열에 입력하고 출력 시에 그 배열에서 값을 가져온다는 부분만이 다르기 때문에
그리 어렵지 않을 거라고 생각됩니다.
이번 글에서는 C언어의 배열에 대해서 알아보았습니다.
다음 글에선 C언어의 꽃이라고 말할 수 있는 포인터에 대해서 알아보도록 하겠습니다.
감사합니다.
'프로그래밍 언어 > C언어' 카테고리의 다른 글
C언어 12. 배열과 포인터 (0) | 2020.07.15 |
---|---|
C언어 11. 포인터 (0) | 2020.07.14 |
C언어 9. 사용자 정의 함수 (0) | 2020.07.12 |
C언어 8. 계산기 프로그램 (0) | 2020.07.12 |
C언어 7. 반복문 (0) | 2020.07.11 |