[잼민이도 이해하는 C언어 강의] 9. 배열 / #array,#문자열
지난 강의에서는 반복문과 조건문에 대해서
학습하며 대표적인 프로그래밍 문법에 대해서 알아보았습니다.
반복문은 반복적으로 실행되는 구조를 만들어냄으로서
코드를 편리하게 작성할 수 있는
엄청난 문법이었습니다.
이번에는
한꺼번에 여러개의 데이터를 편리하게 처리할 수 있도록 도와주는
기본적인 자료구조인 배열에 대해서
알아보도록 하겠습니다.
1. 배열이란? |
2. 배열 사용 방법 |
3. 문자열이란? |
배열은 변수처럼 데이터를 저장하는 공간입니다.
변수에는 최대 1개의 데이터만 보관할 수 있었지만
배열에는 여러 개의 데이터를 저장할 수 있습니다.
배열의 종류는 변수와 마찬가지로
저장하고자하는 데이터의 자료형에따라
정수형 배열, 실수형 배열, 문자형 배열로 나뉩니다.
이때 문자를 저장하는 배열은 문자열이라고도 부릅니다.
문자를 저장하는 배열만 특별한 명칭이 있는 이유는
문자열만의 독특한 처리방법 때문입니다.
1. 배열이란?
배열은 변수처럼 데이터를 저장하는 공간입니다.
변수와 다른 점은
변수는 데이터를 한번에 한 개만 저장할 수 있었던 반면,
배열은 여러 개의 데이터를 저장할 수 있는 공간이라는 점입니다.
변수를 선언하고, 사용하듯이
똑같이 배열도 선언해서 사용해야 합니다.
아래 코드를 보겠습니다.
#include<stdio.h>
int main()
{
int arr[5];
arr[0] = 10;
arr[1] = 11;
arr[2] = 20;
arr[3] = 30;
printf("%d %d %d",arr[2],arr[3],arr[4]);
return 0;
}
int arr[5]; 는 배열을 선언하는 부분입니다.
int 를 사용한 것은 정수 데이터를 저장할 배열을 만들겠다는 것입니다.
즉, 배열의 자료형입니다.
arr는 배열의 이름입니다.
그리고 뒤에 [ ] (대괄호)는 배열의 크기를 정의합니다.
여기서 배열의 크기란, 배열에 저장할 데이터의 수를 말합니다.
정리하자면
정수를 저장하는 5칸의 배열을 선언한 것입니다.
arr[0] = 10;
arr[1] = 11;
arr[2] = 20;
arr[3] = 30;
이 부분은 데이터를 대입하는 과정입니다.
arr[0], arr[1], arr[2], arr[3]에서
0, 1, 2, 3은 방 번호를 의미합니다.
int arr[5]; 배열의 선언부를 설명할 때
[5]는 배열의 크기 즉, 저장할 데이터의 개수를 의미한다고 했습니다.
그렇다면 int arr[5]는 총 5개의 변수나 다름이 없는 것입니다.
다만, 변수의 경우에는 변수 이름이 다 다르기때문에
원하는 변수에 원하는 데이터를 저장할 수 있지만
배열의 경우에는 모든 방이 arr라는 동일한 이름을 갖고 있습니다.
그래서 배열에는 방 번호라는 개념이 있습니다.
이 방 번호 이용해서 배열에서 원하는 칸에 원하는 데이터를 저장하는 것이죠.
배열의 이름은 마음대로 정할 수 있지만
방 번호는 반드시 0부터 시작됩니다.
위 코드의 경우 5칸의 배열을 만들었으므로
0, 1, 2, 3, 4의 방 번호가 부여됩니다.
배열 이름에 [방 번호]를 붙여
배열을 사용할 수 있습니다.
이제 출력 결과를 봅시다.
printf("%d %d %d",arr[2],arr[3],arr[4]);
2번방과 3번방은 저장한대로 잘 출력이 되었지만
4번방은 0이 출력되었습니다.
"4번방은 데이터를 저장한 적이 없는데요??"
이는 쓰레기값입니다.
쓰레기값이란 말 그대로
쓰레기 데이터를 의미합니다.
쓰레기값은 컴퓨터 환경마다 그리고 실행 환경마다 달라질 수 있습니다.
초기화하지 않은 변수에는
항상 쓰레기값이 들어있습니다.
배열도 마찬가지로
초기화를 하지 않은 4번 방에는
쓰레기값이 들어있게 됩니다.
따라서 따로 저장한적도 없는
쓰레기값인 0이 출력된 것입니다.
C언어 변수에 대한 강의에서
변수 초기화를 설명한 적이 있습니다.
int A = 10;
처럼 변수 선언과 동시에
데이터를 저장하는 방법이었습니다.
배열도 이러한 초기화가 가능합니다.
아래 코드를 확인해 봅시다.
#include<stdio.h>
int main(void)
{
int arr[5] = {1,2,4,8,16};
printf("%d %d %d",arr[1],arr[2],arr[3]);
return 0;
}
{ } 중괄호를 선언부에 사용하여
중괄호 내부에는 배열에 저장하고자하는
데이터를 ,콤마로 구분하여 작성합니다.
그러면 순서대로 0번방부터 데이터가 초기화됩니다.
#include<stdio.h>
int main(void)
{
int arr[5] = {1,2};
printf("%d %d %d",arr[0],arr[1],arr[2]);
return 0;
}
하지만 반드시
모든 배열의 방에 데이터를 채워넣어야 하는 것은 아닙니다.
위 코드처럼 데이터를 방 개수보다 부족하게 작성하게 된다면
데이터가 들어가지 않은 방은
자동으로 0이 채워집니다.
위에서 언급했던 쓰레기값인 0이 아니라
항상 올바른 데이터로 0이 채워집니다.
2. 배열 사용 방법
배열은 이처럼
여러개의 데이터를 관리하기 용이합니다.
"하지만 배열의 방이 백개, 천개, 만개 라면??"
네... 문제가 있을 수 있습니다.
위의 코드들처럼 하나 하나 저장하고, 출력해야 된다면 말입니다.
코드를 작성하기 매우 힘들어집니다.
그래서 배열은
for 반복문과 함께 사용합니다!
아래 코드를 확인해봅시다.
#include<stdio.h>
int main(void)
{
int i, arr[5];
for(i=0;i<5;i++)
{
printf("%d번째 데이터 : ",i);
scanf("%d",&arr[i]);
}
for(i=0;i<5;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
for 문을 이용하여
i를 0부터 4까지 반복시켰습니다.
내부에는 scanf를 이용하여
arr[i]에 입력을 받기로 했습니다.
i는 for문을 통해 0~4까지 증가되어
scanf하나로 0번방부터 4번방까지 입력을 받을 수 있게됩니다.
출력도 마찬가지입니다.
for문을 통해 arr[i]를 출력했습니다.
i는 0~4까지 증가되며 순서대로
0번방부터 4번방까지 출력을 할 수 있게됩니다.
이처럼 배열은 반복문과 거의 함께 사용된다고 보시면 됩니다.
이 방법은 배열의 방이 10개, 100개, 백 만개여도 상관이 없습니다.
여담이지만,
반복문 for문을 학습할 때
영문도 모른채 우리는 인자로 i를 사용했었습니다.
배열의 방 번호는 영어로 하면 index입니다.
첫 글자가 i입니다. index에서 유래된것이죠.
for문은 배열의 단짝 친구입니다.
3. 문자열이란?
문자열은 단어 그대로
'문자를 저장할 수 있는 배열'입니다.
"저희 변수 강의에서 문자열 배우지 않았던가요?"
네 맞습니다.
잠깐 강의 진행의 편의를 위해
문자열을 변수로 소개했습니다.
사실 문자열은 배열입니다.
문자열에 관한 대부분의 내용은
변수 강의에서 학습한바있지만
문자열을 배열로써 다시 강의하겠습니다.
#include<stdio.h>
int main(void)
{
char arr[20] = "Hello World";
printf("%c %c %c\n",arr[0],arr[2],arr[8]);
return 0;
}
위 코드는 문자열을 선언한 코드입니다.
아시다시피
앞선 변수 강의에서 저희는 문자열에 대해서 학습한 바 있습니다.
문자열은 위 코드처럼 char형 배열로 선언되어
사용할 수 있습니다.
문자열 역시 배열의 일종이기 때문에
위에서 설명드린 배열의 사용 방법과 동일합니다.
그러나 추가적으로
문자열은 코딩의 편의를 위해
남다른 사용방법을 가지고 있습니다.
첫 째,
초기화시에 { } 중괄호가 아닌 " " 큰따옴표를 통해 초기화를 할 수 있습니다.
자료형에서 배웠던 내용처럼 문자열은 " "로 표기합니다.
초기화시에도 정수 배열과 실수 배열과는 달리
" "로 편리하게 문자열을 초기화할 수 있습니다.
물론, char arr[10] = {'H', 'e', 'l', 'l', 'o'} 와 같은 방법으로
{ } 중괄호를 통해 초기화하는 것도 가능합니다!
둘 째,
%s라는 문자열 변환문자가 존재한다.
#include<stdio.h>
int main(void)
{
char arr[20];
printf("문자열을 입력하세요. ");
scanf("%s",arr);
printf("입력한 문자열 : %s",arr);
return 0;
}
정수 배열이나 실수 배열과는 달리
문자열은 변환 문자가 존재합니다.
문자열 편애
다른 배열은 입출력시에
방번호 index를 지정하여 입력받거나 출력해야하기에
거의 필수적으로 반복문을 함께 사용해야 합니다.
하지만,
문자열은 %s라는 강력한 변환문자덕분에
문자열을 입력받거나 출력하는 것이
매우 편리합니다.
주의할 점은
scanf를 통해 문자열을 입력받을 때는
다른 자료형과는 달리
& 연산자를 사용하지 않는 것입니다.
그 이유는 추후 포인터 강의에서 다시 자세히 다뤄보겠습니다.
그러나 변수 강의에서 확인했던
문자열의 치명적인 문제점이 있었으니
문자열을 바꿀 수 없는 문제점이었습니다.
#include<stdio.h>
int main()
{
char arr[10];
arr = "Hello";
printf("%s",arr);
return 0;
}
위 코드는 컴파일이 불가능합니다.
배열에서의 = 대입연산자는
반드시 [ ] 방 번호가 함께 지정되어야 합니다.
문자열이라고 다를 건 없습니다.
이럴 때는 두 가지의 방법이 있습니다.
#include<stdio.h>
int main(void)
{
char arr[10];
arr[0] = 'H';
arr[1] = 'e';
arr[2] = 'l';
arr[3] = 'l';
arr[4] = 'o';
arr[5] = '\0';
printf("입력한 문자열 : %s",arr);
return 0;
}
첫 번째 방법,
배열 방 하나 하나 직접 넣는다.
쉬운 방법은 아니지만 틀린 방법도 아닙니다.
노가다...
arr[5] = '\0';
이건 뭘까요?
변수 강의에서도 한번 등장한 적 있는 '\0'는 널 문자입니다.
변수 강의에서는 '\0' 널 문자의 존재만 알려드렸지만
조금 더 자세히 알려드리자면
'\0' 는 문자열의 마지막 방을 표시하기 위해
꼭 필요합니다.
단순히 printf의 %s를 통한 출력만 보더라도
배열 전체를 출력하는데
선언한 배열 전체를 출력해버리면 쓰레기값이 출력될 수 있는 문제점이 발생합니다.
실제로 위 코드에서도 arr[5] = '\0'; 없이 컴파일하면
알 수 없는 쓰레기값이 출력되고 맙니다.
이처럼 '\0' 널 문자는 문자열의 마지막 방을 표시함으로써
문자열을 처리하는 데 생길 수 있는
다양한 문제들을 보완하는 중요한 역할을 수행합니다.
#include<stdio.h>
#include<string.h>
int main(void)
{
char arr[10];
strcpy(arr, "Hello");
printf("입력한 문자열 : %s",arr);
return 0;
}
두 번째 방법,
strcpy() 활용하기
첫 번째 방법은 너무 힘든 방법입니다.
Hello는 짧았지만 더 긴 문자열은
코드를 작성하는 데 더 많은 시간을 소요하게 할 것입니다.
따라서 C언어는 문자열을 편리하게 사용할 수 있도록
다양한 문자열 연산 함수를 제공합니다.
그 중에 하나가 strcpy() 입니다.
strcpy()는 원하는 문자열을 저장할 수 있도록 해주는 함수입니다.
하지만,
strcpy는 상단에 #include<stdio.h>와 함께
#include<string.h>를 함께 작성해야
사용할 수 있습니다.
그 이유는 다음 강의인 함수 강의에서 다시 알아보도록 하겠습니다.
또 다른 종류의 문자열 연산 함수 역시
지금은 아직 알 필요가 없습니다.
따로 문자열 연산 함수 강의를 통해 알아보도록 하겠습니다.
이렇게 오늘은 배열이라는
자료구조를 학습해보았습니다.
배열을 활용한다면
여러개의 데이터를 동시에 관리할 수 있으며
여러개의 데이터를 동시에 처리할 수 있기에
데이터 관리 측면에서 매우 유리해집니다.
다음 강의에서는 함수에 대해서 학습해 보겠습니다.
'프로그래밍 > C언어' 카테고리의 다른 글
[잼민이도 이해하는 C언어 강의] 8. 반복문 / #while, #for, #do-while (0) | 2022.05.20 |
---|---|
[잼민이도 이해하는 C언어 강의] 7. 조건문 / #if, #else if, #else (0) | 2022.04.18 |
[잼민이도 이해하는 C언어 강의] 6. 연산자 / #산술연산자, #관계연산자, #논리연산자 (0) | 2022.04.15 |
[잼민이도 이해하는 C언어 강의] 5. 입력하기 / #scanf (3) | 2022.04.09 |
[잼민이도 이해하는 C언어 강의] 4. 변수란? / #변수 (1) | 2022.04.08 |