[CodeEater와 제로부터 시작하는 C언어] 4장 - 변수와 자료형과 포맷
저번에 printf라는 함수에 대해서 배웠다.
사실 저번 시간에서 배운 것의 전부라고 할 수 있다.
그 때 이야기했던 것을 복기해보면 printf의 역활은 "" 내부의 내용을 출력하는 것이라고 하였다.
그렇기 때문에 여러분은 조금만 이를 수정하면 여러분이 원하는 것을 출력할 수 있다.
이런것을 알렴련 여러분은 변수를 알아야한다.
이번 시간에 배울 것은 변수(Variable), 자료형(Data Type), 서식 지정자(Format Specifier), 제어 문자(Escape Sequence)에 대해서 배울 것이다.
그리고 변수(Variable), 자료형(Data Type), 서식(Format), 서식 지정자(Format Specifier), 제어 문자(Escape Sequence), 접두사(Prefix), 접미사(Suffix)라는 용어를 새로 듣게 될 것이다.
#include <stdio.h>
int main() {
printf("나는 오늘 밥을 먹었다. 맛있었다.");
return 0;
}
위처럼 코드를 작성한다면 우리는 밥을 먹었다는 출력값을 볼 수 있다.
하지만 사실 필자는 밥보다는 고기가 좋다.
그래서 고기로 출력해보고 싶다.
#include <stdio.h>
int main() {
printf("나는 오늘 고기를 먹었다. 맛있었다.");
return 0;
}
기특하게도 여러분은 고기로 수정할 수 있다.
사실 여러분도 고기가 더 좋을테니 틀린말이 아닐 것이다.
문제는 여기서 발생한다.
만약 고기가 아니라 존재하진 않겠지만 야채라면?
콜라라면? 약이라면? 플라스틱이라면?
이렇게 바뀐다면 여러분은 계속해서 printf의 내용을 수정해줘야한다.
이는 솔직히 말해서 귀찮다.
코드가 적으면 귀찮다라는 아주 심플한 말로 끝나지만
좀 많아진다면 귀찮다는 가벼운말로 정할수 없게 된다.
그래서 우리는 한번 정해서 쓸 수 있는 변수라는걸 프로그래밍에 도입하게된다.
변수는 우리가 흔히 수학에 아는 변수와 똑같다고 생각하면된다.
변수를 설명할때는 뭔가를 담는 그릇이나 박스라고 설명하는 경우가 많다.
그런데 오랫동안 이렇게 식상하게 설명하니까 카멜레온을 예시로 들겠다.
변수는 카멜레온같은 녀석이다.
카멜레온이 색을 변경할 수 있듯이 변수는 값을 바꿀 수 있다.
아래는 변수를 사용하고 이를 출력하는 예제이다.
#include <stdio.h>
int main() {
int num = 27;
printf("나의 나이는 %d다!", num);
return 0;
}
여기서 모르는 개념이 추가되었는데 나눠서 보자.
int num = 27;
int라는 것은 integer의 줄임말이다.
integer의 뜻은 정수라는 뜻이다.
말그대로 정수 값만 집어넣을 수 있기 때문에 소수형태의 값은 저장할 수 없다.
위의 코드 한줄 짜리를 해석해보면
"정수 변수 num이 있는데 값은 27이다."라는 뜻이다.
만약 소수 형태로 저장을 시도한다면 소수점을 날려버리고 정수만 취하게 된다.
위의 예시는 선언과 동시에 초기화를 한 것이다.
변수는 위같은 방식이 아니라
아래처럼 사용도 가능하다.
int num; // - (1)
num = 27; // - (2)
여기서 1번의 int num은 값을 집어넣지 않았다.
이런경우를 변수의 선언이라고 한다.
2번의 경우는 선언을 한 후 초기화를 한 것이다.
여기서 중요한것은 만약 초기화를 하지 않았다면 어떻게 되느냐일 것이다.
백문이 불여일견이니 한번 코드를 수정해서 실행해보자.
#include <stdio.h>
int main() {
int num;
printf("나의 나이는 %d다!", num);
return 0;
}
비주얼 스튜디오 2019에서는 빌드를 거부한다.
어떻게든 빌드를 시킬 수는 있지만 그 방법을 여기서 논하지는 않겠다.
필자가 해본 결과, 에러를 무시하고 빌드할 경우(공식적으로는 아직 에러가 아니다.)
저 자리에 0이 출력되는걸 확인할 수 있었다.
하지만 기본적으로는 0이 출력되는게 아니다.
위는 맥에서 실행한 화면이며 아래에는 결과값을 볼 수 있다.
비주얼 스튜디오도 옜날버전은 위처럼 동작하므로 위를 기준으로 설명하겠다.
일단 두가지의 문제가 있는데 num을 초기화 하지 않아도 프로그램이 정상작동을 하게된다는점.
두번째로는 num의 값을 특정지을 수 없다는 점이다.
그 이유를 설명하려면 복잡한데 어쨋든 결과만 간단히 말하자면
num은 초기화를 하지 않았지만 이상한 값을 가지고 있게 된다.
이러한 값은 아무런 의미가 없다. 이러한 값을 쓰레기(Garbage, 가비지)라고 부른다.
이는 아무 의미 없는 값이지만 사용자 입장에서는 이게 의미 있는 값인지 없는 값인지 모른다.
가령 여러분이 위의 예제에서 num이 194842661 이런수가 나왔다면
의미 없는 수라고 생각하겠지만 실제로 194842661라는 숫자를 쓸수도 있지 않은가.
그래서 여러분이 변수를 사용할 때는 항상 초기화 작업을 해주어야한다.
위에서 변수를 한번 지정하고 나면 타입은 바뀌지 않는다.
예를 들어서 카멜레온이 색은 변할 수 있어도 다른 종류의 카멜레온은 될 수 없는것 처럼 말이다.
그래서 다른 언어에서는 변수는 마치 메타몽 처럼 타입도 바꿀 수 있지만
C언어에서는 메타몽 보다는 카멜레온에 더 가깝다고 볼 수있다.
변수를 printf에서 사용하는 예시는 아래와 같다.
printf("나의 나이는 %d다!", num);
이 코드는 고작 몇개가 바뀌었지만 여러분의 프로그래밍 인생에서 엄청난 변화가 있을 것이다.
바로 변수를 사용하는 법을 알게 된것이다.
%d라는 것은 서식 지정자(Format Specifier)라는 것이다.
이러한 서식 지정자는 %와 알파뱃의 조합으로 이루어진다.
위의 d는 Decimal, 즉 십진수 출력을 의미한다.
%d라는 녀석이 붙어있다면 그 뒤에 변수가 선언되어있는지를 확인해서 없다면 쓰레기 값이 출력된다.
#include <stdio.h>
int main() {
int num = 27;
printf("나의 나이는 %d다!");
return 0;
}
이 경우에도 %d자리에 쓰레기 값이 출력하게된다.
또한 변수를 여러개나 혹은 서식 지정자를 여러개 사용할 수 있다.
#include <stdio.h>
int main() {
int num1 = 27;
int num2 = 2018;
printf("나의 나이는 %d다! %d!", num1, num1);
printf("나의 나이는 %d년 현재 %d다!", num2, num1);
return 0;
}
이 경우 %d라는 서식 지정자가 한 printf함수에서 두개씩 존재한다.
결과를 보면 각각에 매칭되는걸 알 수 있다.
위의 printf는 같은 변수를 두번 사용하였고 아래의 printf는 다른 변수를 각각 한번씩 사용하였다.
사용할 변수들은 사용된 서식 지정자의 숫자와 맞추어주어야한다.
위를 출력해보면 알겠지만 printf를 각각 나눠쓰더라도 두 문장은 붙혀서 출력이 될 것이다.
그 이유는 두 printf의 문장 사이에 공백을 입력해주는 문자를 넣지 않아서다.
우리의 목표가 공백을 출력하지 않는거라면 뭐 상관없지만 공백을 출력해야한다면 이는 문제가된다.
그런데 공백을 도대체 어떻게 표현해야할까?
이러한 특수한 문자들을 출력하기 위 무언가가 필요하다는걸 직감적으로 알 수 있다.
#include <stdio.h>
int main() {
int num1 = 27;
int num2 = 2018;
printf("나의 나이는 %d다! %d!\n", num1, num1);
printf("나의 나이는 %d년 현재 %d다!", num2, num1);
return 0;
}
그래서 이를 출력하기 위해서 제어 문자라는 것을 쓴다. 영칭인 이스케이프 시퀀스라고도 많이 부른다.
이를 사용해서 우리는 "한칸 띄우고"라는 의미를 출력할 수 있다.
이제 붙혀서 출력하지 않고 따로 출력하게 될 것이다.
제어 문자도 여러종류가 있는데 여기서 설명하기는 좀 길기 때문에 추후에 언급하겠다.
일단 사용한 부분만 설명하자면 \도 %때와 마찬가지로 알파벳의 조합으로 이루어진다.
\n은 Line Feed(보통 줄여서 LF라 한다.)라는 의미를 담고 있는데
한국에서 말하는 Line Feed는 강제 개행이라는 의미를 담고있다.
강제 개행은 줄바꿈이라는 뜻이기 때문에 줄이 바뀌어 지게된다.
지금 까지 변수, 자료형, 서식 지정자에 대해서 알았다.
여기서 우리가 사용한 변수의 자료형은 10진수였고 서식 지정자는 %d를 사용하였다.
그러면 다른 종류도 있느냐고 반문할 수 있다.
당연히 있다!
우리는 정수만 다뤘는데 정수 말고도 다른 타입이 존재하면 심지어 정수도 여러가지의 타입이 존재한다.
이에 대해서 다... 알아보기에는 너무 서면이 길어지기에 추가 포스팅으로 언급하겠다.
이번에는 정수말고 실수를 쓰는 법을 보도록하자.
#include <stdio.h>
int main() {
float f1 = .1f;
float f2 = 4.14f;
printf("너랑 나랑 사귈 확률? %f야!\n", f1);
printf("원의 원주율? 그것도 모르냐? %f지!", f2);
return 0;
}
처음으로 실수라는 개념을 배우게 되겠지만 보통 실수라고 하진 않고 소수라고 하는 경향이 있다.
C에서 사용하는 실수(소수)는 부동소수점이라는 방식을 채택하는데 여기서 설명하기엔 길어지므로 생략하겠다.
c에서의 실수형 float은 특이한 성질이 몇가지 있다.
첫번째로 접미사(Suffix)가 붙는다는 점이다.
우리가 int를 정의할때 접미사는 없었지만 float을 정의할 때는 접미사가 필요하다.
또한 만약 값에 정수부가 0이라면 0.은 생략할 수 있다.
써도 상관없고 안 써도 상관없다. 이건 정말 스타일 대로라서 어떤사람들은 칼같이 안쓰는 반면
어떤 사람들은 0.을 붙혀주는 경우도 많다.
당연하지만 정수부가 0이아니라면 무조건 정의해줘야한다.
이제 데이터 타입에 대하여 int와 float을 배웠다.
그럼 이 두놈만 있느냐? 이 또한 당연히 아니다.
아래는 다른 변수들이다.
몇가지 주의해야할 점이 있기에 짚고 넘어가겠다.
현재는 별로 안중요할 수 있는 내용이지만 크기에 대해서 잠시 논하려고한다.
1. 문자 타입이란건 사실 없다
- 아직 문자를 배우지는 않았지만 실제로 문자 타입이라는건 존재하지않는다. char에 문자 타입이라고 적은건 그냥 여러분들이 앞으로 하면서 배우기 쉽게하려고 한 말이다. 그러나 아직까지는 문자 타입이라고 생각하는게 편하다.
2. 크기는 고정되어 있지 않다
- 위의 크기(byte)를 적어두었지만 사실 크기가 정확히 정해진건 char뿐이고 나머지는 상대 크기로 언제든지 바뀔 수 있다. 다만 현재 C표준에서는 가급적 크기를 위와 같이 맞추려는 경향이 있을 뿐이다. 머신에 따라서 조금씩 차이는 있다.
3. 진리값은 그냥 쓸 수 없다
- 아직 진리값을 배우지 않았지만 진리 값은 그냥 쓸 수 없다. 상단에 #include<stdbool.h>를 추가해야 사용할 수 있다.
4. 서식 지정자는 사실 고정이 아니다
- 서식 지정자의 대응을 적어뒀지만 사실 고정이 아니며 저렇게 복잡하게 쓰는 사람이 오히려 드물 것이다. 하지만 이도 추후에 논하도록 하겠다.
5. 접미사는 대소문자를 가리지 않는다
- 말그대로 가리지 않기 때문에 4.3f나 4.3F나 동일하다
이번 시간에 아주 많은 것을 배웠는데 사실 축약해보면 많지 않다.
다음 시간에는 5장인 입력과 출력으로 넘어갈 것이다.
다만 4장에서 추가적인 부록으로 1, 2 편을 준비했으니 시간남으면 읽어보길 바란다.
'제로부터 시작하는 프로그래밍 > C' 카테고리의 다른 글
[CodeEater와 제로부터 시작하는 C언어] 4.2장 - 서식 지정자 (0) | 2019.11.30 |
---|---|
[CodeEater와 제로부터 시작하는 C언어] 4.1장 - 변수는 어떻게 표현되는가 (0) | 2019.11.23 |
[CodeEater와 제로부터 시작하는 C언어] 3장 - 프로젝트 만들기/첫프로그램 (0) | 2019.11.12 |
[CodeEater와 제로부터 시작하는 C언어] 2장 - C언어란 무엇인가 (0) | 2019.11.11 |
[CodeEater와 제로부터 시작하는 C언어] 1장 - C언어를 배우는 이유 (0) | 2019.11.11 |