본 내용은 해당 강의 토대로 작성
배열
배열은 연속된 데이터의 변수를 가질 수 있는 자료형이다. 여러 개의 변수를 동시에 생성하는 것과 같다.
배열의 선언은 아래와 같다.
자료형
배열명[배열 범위
];배열명[
인덱스
] = 값;…
자료형
: 배열 값의 자료형이다. C에서의 배열은 한 자료형만 가질 수 있다.
배열 범위
: 배열이 가질 데이터의 수
인덱스
: 각 배열값의 번호. 첫 번째 배열의 번호는 0번이다.
배열의 구체적인 예시를 들어보자.
#include <stdio.h>
int main(void)
{
int subway_array[3]; //정수형 변수 3개 인덱스는 0부터 시작 [0],[1],[2]
subway_array[0] = 30;
subway_array[1] = 40;
subway_array[2] = 50;
for(int i = 0; i < 3; i++)
{
printf("지하철 %d호차에 %d명이 타고 있습니다\n", i+1, subway_array[i]);
}
return 0;
}
값 설정
C언어에서 배열의 값을 설정할 때, 여러가지의 경우를 분석해보자.
#include <stdio.h>
int main(void)
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
for (int i =0; i < 10; i++)
{
printf("%d\n", arr[i]); // 1,2,3,4,5,6,7,8,9,10 출력
}
return 0;
}
배열을 정상적으로 선언하고 사용한 경우이다.
배열 초기화
#include <stdio.h>
int main(void)
{
int arr[10]
for (int i = 0; i < 10; i++)
{
printf("%d\n", arr[i]); // 오류 발생
}
return 0;
}
배열을 선언하고 값을 초기화(입력)하지 않으면 이상한 숫자가 나온다. 이것은 컴퓨터마다 다르게 나오며, 이를 더미값, 쓰레기값이라고 한다. 그러므로 항상 값은 초기화를 해야한다.
배열의 범위
#include <stdio.h>
int main(void)
{
int size = 10;
int arr[size]; //배열 선언할 시 변수로 사용할 수 없다.오류발생
return 0;
}
위의 경우, 변수 size
에 정수값을 대입하고 size
를 배열의 범위로 주었을 때, 오류가 발생하게 된다. 항상 상수로 주어야 한다.
일부 값만 대입했을 때
#include <stdio.h>
int main(void)
{
int arr[10] = {1,2};
for(int i = 0; i < 10; i++)
{
printf("%d\n", arr[i]); //3번쨰 값 부터는 자동으로'0'으로 초기화 됨
}
return 0;
}
배열을 선언할 때, 일부 인덱스에만 값을 넣어준 경우이다. 두 번째 값까지 정의한 배열값이 출력되고, 그 이후는 0이 출력된다.
바로 범위설정하기
#include <stdio.h>
int main(void)
{
int arr[] = {1,2}; // arr[2]와 같음
return 0;
}
배열을 선언할때 배열범위를 넣지 않고 중괄호로 바로 넣어줄 수 있다.
실수형 배열
#include <stdio.h>
int main(void)
{
float arr_f[5] = {1.0f, 2.0f, 3.0f};
for (int i = 0; i < 5; i++)
{
printf("%.2f\n", arr_f[i]);
}
//1.00 2.00 3.00 0.00 0.00
return 0;
}
실수형 float
로 배열을 선언할 수 있다.
문자 vs 문자열
문자는 한글자 데이터이고 문자열은 한글자 이상의 여러글자이다. 문자와 문자열을 다루는 방법들을 알아보자.
#include <stdio.h>
int main(void)
{
char c = 'A';
printf("%c\n", c); //A 출력
return 0;
}
문자는 위 처럼 정의한다. 보통 변수를 영문 소문자로 하며, 작은 따옴표를 사용한다. 불러올 때는 %c
를 쓴다.
문자열 끝
#include <stdio.h>
int main(void)
{
char str[6] = "coding";
printf("%s\n", str); //이상한 값 출력
return 0;
}
위의 경우, 이상한 값이 출력된다.(맥의 경우는 오류로 아예 출력이 되지 않음) 이유는, 문자열 끝에는 '끝'을 의미하는 \0
이 포함되어야 하는데, 문자열 str
을 선언할 때, 6자리만 만들었고 문자열이 그 자리를 꽉 채움에따라 \0
이 들어가지 못했다.
#include <stdio.h>
int main(void)
{
char str[7] = "coding"; //[c][o][d][i][n][g][\0]
printf("%s\n", str); //coding 출력
return 0;
}
문자열을 7자리를 만들면 입력한 값이 잘 출력된다. 문자열은 불러올 때 %s
를 사용한다.
문자열 자리수
#include <stdio.h>
int main(void)
{
char str [] = "coding";
printf("%s\n", str); //coding 출력
printf("%d\n", sizeof(str)); //7 출력
return 0;
}
이 경우는 문자열 자리수를 넣지 않고 빈 괄호만을 입력하였다. 자동으로 null을 집어넣어서 정상 출력이 된다.
sizeof
: 변수의 크기를 알아내는 함수
문자열 배열 뽑아내기
#include <stdio.h>
int main(void)
{
char str [] = "coding";
for(int i=0; i <sizeof(str); i++) //7보다 작을때 까지(7번 실행)
{
printf("%c\n", str[i]);
}
return 0;
}
for
문을 사용해서 입력된 문자열 하나하나를 뽑으면, 아래와 같이 출력된다. 이때, 여기서 맨 아래의 빈 공간은 NULL
의 자리이다.
배열- 한글과 영어
#include <stdio.h>
int main(void)
{
char kor[] = "나도코딩";
printf("%s\n", kor);
printf("%d\n", sizeof(kor));
// 영어는 한글자가 1 byte
// 한글은 2byte
// 사이즈 9
// 왜 나는 13?
// 한글 구조상 더 복잡해서 2바이xm
// char 자료형 크기 : 1byte
return 0;
}
영어의 경우, sizeof
함수로 크기를 출력하면 글자수 +1 만큼 나왔다. 하지만, 위의 "나도코딩"을 sizeof
함수로 출력하면 9가 나온다. 이유는 한글과 영어를 다른 방식으로 사용하기 때문이다.
영어는 한글자가 1byte를 사용한다. 그리고 char
자료형의 자체 크기는 1byte이다. "coding"은 6글자이므로 총 7byte, "7"이 출력된다. 반면, 한글은 구조상 더 복잡해서 글자당 2byte가 사용된다. 그래서 "9"가 출력된다.
나의 경우는 macOS를 사용하는데, "13"이 출력되었다. 그래서 웹 서치를 해보았는데, 윈도우의 경우에는 CP949 인코딩에 기반한 완성형 한글을 사용하는 반면 macOS는 UTF-8 방식을 사용한다. UTF-8은 한글이 글자당 3byte를 차지한다. 그러므로 출력된 "13"은 정확한 값이다!
문자열 심화
#include <stdio.h>
int main(void)
{
char c_array[7] = {'c','o','d','i','n','g','\n'};
printf("%s\n", c_array); //coding 출력
return 0;
}
문자열의 선언은 위처럼 문자 하나하나와 NULL
값을 입력하는 것과 같다.
#include <stdio.h>
int main(void)
{
char c_array[10] = {'c','o','d','i','n','g'};
for(int i=0; i < sizeof(c_array); i++)
{
printf("%c\n", c_array[i]);
}
return 0;
}
문자열 선언에서, 여유있게 크기를 만들고 값을 대입한 뒤, 출력을 시키면 문자를 제외한 나머지 자리에는 NULL
값이 들어가 있다.
문자열의 정수형 출력
#include <stdio.h>
int main(void)
{
char c_array[10] = {'c','o','d','i','n','g'};
for(int i=0; i < sizeof(c_array); i++)
{
printf("%d\n", c_array[i]); //ASCII 코드 값 출력
}
return 0;
}
문자열을 출력할 때 포맷을 %d
(정수형)으로 하면 아래처럼 숫자가 출력된다. 이것은 ASCII 코드 값이다. NULL
은 0으로 출력된다.
이전의 경찰서 조서 쓰기 예제에서, 아래와 같은 명령어를 작성하였다.
#include <stdio.h>
int main(void)
{
char name[256]; //크기를 넉넉하게
printf("이름이 뭐예요?");
scanf("%s", name, sizeof(name)); //%s로 입력받아 배열에 값을 입력, 세 번째 인자는 받을 데이터의 제한
printf("%s\n", name);
return 0;
}
입력을 받을 때, 얼마나 긴 문자열이 올지 모르므로 예상되는 최대보다 넉넉하게 하는 것이 오류가 나지 않는다.
ASCII 코드
ASCII 코드란, 미국표준협회(ANSI)에서 제시한 표준 코드 체계이다. 7bit, 총 128개 코드로 0에서 127까지 숫자로 표시한다.
a : 97
A : 65
0 : 48
\0 : 0
이렇게, 문자나 숫자 하나당 코드를 할당하는 방식이다. 컴퓨터 초창기에는 많은 방법으로 문자를 표현하였는데, 호환성 문제가 빈번하였고 이를 해결하기 위해서 표준화가 진행된 것이다.
반복문을 사용해서, 0~127까지 ASCII코드를 조회해보자.
#include <stdio.h>
int main(void)
{
for(int i = 1 ; i <128; i++)
{
printf("아스키 코드 정수 %d : %c\n", i,i);
}
return 0;
}
아빠는 대머리 게임
배열을 사용해서 아빠는 대머리 게임을 만들어보자.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main(void)
{
srand(time(NULL)); //난수 촉
printf("\n\n === 아빠는 대머리 게임 === \n\n");
int answer; //사용자 입력값
int treatment = rand() % 4; //발모제 선택 (0~3)
int cntShowBottle = 0; //이번 게임에 보여줄 병 갯수
int precCntShowBottle = 0; //앞 게임에 보여준 병 갯수
// 서로 보여주는 병 갯수를 다르게 하여 정답률 향상 (처음에 2개 -> 다음에 3개 ...)
//3번의 기회 (3번의 발모제 투여 시도)
for(int i = 1; i <= 3; i++)
{
int bottle[4] = {0, 0, 0, 0}; //4개의 병을 배열로 입력
do {
cntShowBottle = rand() % 2 + 2; //보여줄 병 갯수 (0~1 +2 -> 2,3)
} while(cntShowBottle == precCntShowBottle); //정답률 향상을 위해 현게임과 전게임의 보여준 병 갯수가 같으면 난수 뽑기 반복
precCntShowBottle = cntShowBottle; //뽑힌 병 갯수를 앞 게임에 보여준 병 갯수에 입력
int isIncluded = 0; //보여줄 병 중에 발모제가 포함되었는지 여부
printf("> %d 번째 시도 : ",i);
// 보여줄 병 종류를 선택
for(int j=0; j <cntShowBottle; j++)
{
int randBottle = rand() %4; // 0~3 난수 입력
// 아직 선택되지 않은 병이면, 선택 처리
if (bottle[randBottle] == 0)
{
bottle[randBottle] =1; //배열의 인덱스 난수번에 1을 입력
if(randBottle == treatment) //난수가 발모제와 같을때
{
isIncluded = 1; //보여줄 병에 발모제가 포함
}
}
//이미 선택된 병이면, 중복이므로 다시 선택
else
{
j--; //한번 더 반복해야하므로 j를 -1
}
}
// 사용자에게 문제 표시
for (int k =0; k<4; k++) //세 번의 문제 표시 0~3
{
if(bottle[k] == 1) //배열에 1(보여줄 병)이 있으면
printf("%d ", k + 1); //해당 병 번호 출력 (1차이나므로 +1)
}
printf(" 물약을 머리에 바릅니다\n\n");
if (isIncluded == 1) // 발모제가 있을 경우
{
printf(" >>성공 ! 머리가 났어요 !!\n");
}
else // 발모제가 없을 경우
{
printf(" >>실패 ! 머리가 나지 않았어요.. ㅠㅠ\n");
}
printf("\n ... 계속 하려면 아무키나 누르세요 ...");
getchar(); //사용자가 key를 입력할 때 까지 대기
}
printf("\n\n발모제는 몇 번일까요?");
scanf("%d", &answer);
if(answer == treatment + 1) //정답을 맞췄을 때, treatment는 난수가 0~3이므로 +1
{
printf("\n >> 정답입니다!\n");
}
else //오답처리
{
printf("\n >> 땡 ! 틀렸어요. 정답은 %d 입니다\n", treatment+1);
}
return 0;
}
getchar()
사용자가 key를 입력할 때 까지 대기
느낀점
문자열을 배우면서, OS마다 문자열 사용 방식이 다르다는 것을 알게 되었다!
프로젝트는 이번에도 재밌었지만, 만들 프로그램에대해서 효율적으로 계획을 세워서 코딩하는 방법은 없을까?
'programming study > C' 카테고리의 다른 글
[나도코딩]C 프로그래밍 - 입문부터 게임 개발까지 (7)(2020.12.29) (0) | 2020.12.29 |
---|---|
[나도코딩]C 프로그래밍 - 입문부터 게임 개발까지 (6)(2020.12.28) (0) | 2020.12.28 |
[나도코딩]C 프로그래밍 - 입문부터 게임 개발까지 (4)(2020.12.27) (0) | 2020.12.27 |
[나도코딩]C 프로그래밍 - 입문부터 게임 개발까지 (3)(2020.12.26) (0) | 2020.12.26 |
[나도코딩]C 프로그래밍 - 입문부터 게임 개발까지 (2)(2020.12.26) (0) | 2020.12.26 |