Layer 7 03-1 과제 (배열 보고서 작성)
오늘은 배열에 대해 알아보겠습니다.
- 우리가 성적 프로그램을 만든다고 생각을 해봅시다!.
그러면 과목이 약 14개 정도 될꺼에요.
그런데 배열이 없다면 한 과목 마다 변수명을 한 개씩 지어주어야 합니다.
그런데 만약 14개가 아니라 45개? 또는 100개? 라면 어떻게 될까요.
이름을 선언하는 것도 기억하는 것도 일이
될 것 입니다. 그럴 때 편하게 쓸 수 있는 "배열"이라는 기능이 있습니다.
배열이란?
-조금 이해가 어렵다면 열차를 생각하시면 이해가
쉬울것 같습니다.
c언어에서 배열이란?
- 여러개의 같은 데이터 형(data type)을 동일한 이름으로 묶은 것을 의미합니다.
- 하나의 배열은 똑같은 자료형을 (int, double, floot, char, ....)을 모아 놓은
변수라고 할 수 있습니다.
※ int형 배열 안에 double형이나 char형의 값은 넣을 수 없으며,
각 배열 요소의 크기는 모두 같습니다.
일차원 배열의 선언과 초기화 방법
- 각 배열의 요소는 array[i]와 같이 표현 되는데, 이 때 'i'를 '첨자'라고 하며 arr과 같은
집단의 묶음을 배열 이름(배열명)이라고 합니다.
- C언어에서 배열은 첨자의 수에 따라 구분되는데, 첨자 1개를 사용하면 1차원 배열,
2개를 사용하면 2차원 배열, 3개를 사용하면 3차원 배열이 됩니다.
ex)
- arr[i]; => 1차원 배열
- arr[i][j]; => 2차원 배열
- arr[i][j][k]; => 3차원 배열
C언어에서 배열의 구조
- c언어의 경우 크기가 n인 배열 arr의 첫 번째 요소는 array[0],
두 번째 요소는 array[1], ...마지막 n 번째요소는 array[n-1]로 나타냅니다.
- 첨자를 아파트 호수라고 보시면 되는데
0호부터 시작하는 아파트라고 보시면 됩니다.
배열의 선언과 선언 방법
- 초기치는 있어도 되고(1), 없어도 배열을 만들수는 있습니다(2).
선언 방법 ex)
1. int a[5];
- 배열명은 a이며, int형의 공간 5개를 만듭니다.
- 배열도 변수와 같이 초기화를 시켜주지 않으면
일반 변수와 같이 쓰레기 값이 들어있습니다.
그러므로 위와 같은 형태로 만들 때는 나중에 꼭 배열을 초기화
시켜주어야 합니다.
2. int a[5]={1,2,3,4,5};
- 배열명은 a이며, int형의 공간 5개를 각각 1,2,3,4,5로 초기화 시킵니다.
3. int a[]={1,2,3,4,5};
- 배열명은 a이며, {...} 안에 데이터 개수 만큼 배열을 만들고, 그 데이터를
이용해 각 요소를 초기화 시킵니다.
- 그러므로 위와 같이 초기화를 시킬 때는 첨자를 쓰지 않아도 됩니다.
4. int a[5]={0,};
- 배열명은 a이며, int 형으로 이루어진 5개의 공간을 모두
0으로 초기화 합니다.
- 다만, 주의할 점은 0만 가능합니다.
주의 할 점
배열의 장점
- 이런 배열의 장점은 무엇일까요?
: 똑같은 성격을 가진 여러개의 자료를 처리하기 위해서 필요한 개수 만큼
변수를 선언하는 것은 매우 비효율적이며 그 수가 더욱 많아진다면 프로그램을
거의 작성하기가 거의 불가능할 수도 있습니다.
배열을 사용하면 같은 이름으로 변수들을 관리하고 활용하기 쉬워집니다.
배열의 사용
-학생 수가 20명인 반의 평균 점수를 구하는 프로그램을 만들 때.
배열이 있는 경우
subject라는 int형 공간 20개로 이루어진 배열을 만들어
for문을 사용해 입력을 받습니다.
sizeof()라는 자료형의 크기를 알아낼 수 있는 함수를 사용하여
subject 배열의 크기를 알아냅니다. -> 20*4(int형의 size)=80
그러므로 int형의 크기만큼 나누기 4를 하면
배열의 몇 개의 요소로 이루어져 있는지 알아낼 수 있습니다.->20개
이를 이용하여 for문의 조건식을 만들었으며,
모두 더한 후 sizeof(subject)/4=20을 이용해 학생 수 만큼 총합을 나눠
평균을 구한 후 값을 출력하였습니다.
배열이 없는 경우
- 하나 하나 출력을 해야했으며 같은 이름으로 처리할 수 없기
때문에 for문도 사용하기 어려웠습니다.
게다가 코드가 너무 많아 가독성도 굉장히 떨어졌으며,
학생수가 조금만 더 늘어나도 프로그램을 굉장히 많이 바꿔야합니다.
실행 결과
문자열 배열
-지금까지 배운 자료형은 int, double, char... 등등이 있었지만
문자열을 다루는 자료형은 없었습니다.
그 이유는 c언어에는 문자열형(string data type)이 없기 때문에였습니다.
그러므로 문자를 처리하는 char형을 여러개 모아(배열)
문자열을 처리하할 수 있게 만듭니다.
문자열 배열의 초기화 방법
※주의: c언어에서 '..' (작은 따옴표)는 문자를 의미하고. "..." (큰 따옴표)는 문자열을 의미합니다.
그러므로 'a'는 문자 a이지만 "a"는 문자열 a라는 점을 꼭 기억해주세요.
1. 첫 번째.
- 기존의 int, double형..등등을 초기화 할 때 쓰던 방식입니다.
근데 마지막의 '\0'은 무엇일까요??
컴퓨터는 사람처럼 똑똑하지 않습니다.
그래서 문자의 마지막이 어디인지 몰라요. 그렇기 때문에
'\0'(원문자)를 사용해 문자열의 마지막이 어디인지 알려주어야 합니다.
2. 두 번째.
- 첫 번째처럼 초기화를 하려고 하면 정말 힘들겠죠?
그러므로 그냥 단어를 한 번에 초기화 시킬 수 있습니다.
그런데 둘의 차이점은 그뿐만이 아닙니다.
두 번째 방법은 원문자를 자동으로 추가해 배열을 만듭니다.
3. 세 번째.
- 다른 배열들과 같이 단순히 char형 변수의 공간 7개를 확보하기만
한 배열입니다. 배열의 안에는 쓰레기 값이 들어 있으므로
프로그램 도중이나 프로그래밍 중 꼭 정상적인 값을 넣어주어야
합니다. 또한, '\0' 문자가 들어가야 할 자리가 필요하므로
데이터의 크기+1만큼의 크기로 배열의 크기를 확보해 주어야 합니다.
3-1. 배열을 초기화 시키지 않았다면?
위와 같이 name이라는 문자열 배열을 초기화 시키지 않고
출력하면 어떻게 될까요?
실행 결과
한글과 영어의 문자열 저장
중요도: ★★★★★
- c언어에서 char형은 1byte짜리 자료형 입니다.
그러므로 한글과 영어의 저장 방식이 조금 다릅니다.
또한 c언어에서 문자라는 것은 1byte의 영어와 숫자를 말하는 것이기
때문에 한글과 특수문자, 한자는 2byte이므로 한글 한 글자라도
문자열로 여겨집니다.
- char = 1byte
- 영어 1글자, 숫자 1개 = 1byte
- 한글, 한자, 특수문자 = 2byte
이렇게 되기 때문에 한글이나 한자, 특수 문자를 배열에 기억시키려면
배열 요소 2개를 사용하여,한글 한 글자를 기억시킵니다.
다시 말해
위 사진과 같다면
name이라는 변수에 영어는 49글자, 한글은 24글자를 저장할 수 있습니다.
문자열을 입력 받는 방법
- 표준 c언어는 scanf("%s",str)과 같이 하면 됩니다.
뭔가 빠졌다고 생각하시지 않나요?
맞아요. 다른 변수와 달리 배열명 앞에 '&'라는 기호가 빠졌습니다.
- scanf() 함수에서 "&"의 의미
'&'는 주소 연산자를 의미하는데,
이 연산자를 다음과 같은 구문으로 사용했을 때
"문자열 포맷 코드" 안의 데이터 형식과 맞는 값을
입력받아 변수의 주소의 저장하겠다."
라는 의미를 가지고 있습니다.
- 그래서? '&'를 쓰지 않는 이유
배열은 여러개의 변수들을 같은 이름으로 묶어 사용
하는 것이라고 보면 되는데. 그렇기 때문에 배열명 자체가
변수의 주소를 나타내므로 문자열 배열을 사용할 때는 쓸 필요가 없습니다.
문자열을 출력 하는 방법(1)
문자열을 어떻게 str을 출력하면 좋을까요??
for문을 돌면서 널문자('\0')이 아닐 때까지 문자를 하나하나 출력합니다.
실행 결과
그런데 항상 이렇게 반복문을 돌면서 어렵게 해야 할까요??
당연히 아니죠. 저희에겐 printf() 함수가 있습니다.
문자열을 출력 하는 방법(2)
위와 같이 단순히 printf() 함수만 사용하여
위 실행 결과와 똑같이 문자열 출력도 가능합니다.
번외 추가적인 TMI
- vs에서 scanf를 ms에서 쓰지 못하게 하는 이유
scanf() 함수는 오래된 함수라서
보안상 문제가 있습니다. 입력받을 데이터의 크기를
받지 않기 때문에 다른 데이터도 무단으로 빼가거나
변조가 가능합니다. (버퍼 오버플로우라고 합니다.)
그래서 이런저런 이유로 Ms 사에서는 사용
하지 말라고 권하고 있습니다.
해결방안으로는 scanf_s() 함수를 쓰면 되는데
그냥 scanf() 함수를 쓰고 싶으신 분은 VS에서 프로젝트를
만들 때 SDL을 끄고 하시거나 stdio.h 헤더파일을 불러와서 맨 위에
#pragma warning을 쓰면 됩니다.
# scanf(). scanf_s() 어떤 점이 다른가??
scanf()와 scanf_s()함수의 다른 점은
scanf_s() 함수는 배열의 사이즈도
적어주어야 합니다.
2차원 배열
아까 위에서 말했듯이
첨자를 2개를 사용하면 2차원 배열이 됩니다.
int array[행][열];
ex) int array[2][5]; => 2차원 배열
이러한 이차원 배열을 어디에 쓸 수 있을까요??
예를 들면 한 사람의 시험 점수가 아니라 반 학생들 모두의 국어, 수학, 영어 과목의
점수를 저장할 때 다음과 같이 사용할 수 있을것 같습니다.
반 학생이 5명이라고 가정하고 이차원 배열을 만들었습니다.
절때 모두 쓰기 귀찮아서 그런건 아닙니다.
만약 다음과 같은 공간에 값을 입력 받으려면
for문을 중첩하여 입력을 받으면 됩니다.
다차원 배열
다차원 배열은 첨자를 여러개를 쓰는 배열을 말합니다.
ex)
- arr[i]; => 1차원 배열
- arr[i][j]; => 2차원 배열
- arr[i][j][k]; => 3차원 배열
위와 같은 형태로 3차원 배열을 만들 수 있으며,
3D 게임을 짤 때 사용할 수 있을거 같네요.
그리고 학교의 모든 반의 모든 아이들의 성적을 학생, 반 별로 이렇게
구분하여 데이터를 관리 할 때도 위와 같은 다차원 배열이 쓰입니다.
긴 글 봐주셔서 감사합니다!!.
틀린 부분이나 아쉬운 부분이 있으시면 댓글로 남겨주세요.
또한, 사진&그림의 출처가 남겨지지 않은 모든 참고 자료들은
쓰셔도 되지만 꼭 출처를 남겨주시길 바랍니다.