티스토리 뷰

반응형

이전 글

2021/01/24 - [코딩 공부/C 언어] - C언어 기초 : 자료형

C언어 기초 : 자료형

이전 글 2021/01/24 - [코딩 공부] - C언어 기초 : 변수 C언어 기초 : 변수 이전 글 2021/01/17 - [코딩 공부] - C 언어 기초 : 2진수, 8진수, 16진수 등등... 진법 C 언어 기초 : 2진수, 8진수, 16진수 등등.....

hgu-can.tistory.com

이전 포스트에서 자료형까지 알아보았습니다. 

오늘 알아볼 것은 암시적 형변관과 명시적 형변환인데 단어만 봐도 벌써 어려워 보이죠?

근데 내용은 별 거 없습니다. 

100% 이해가 되지 않으신다면 그냥 이런 것이 있구나 정도로만 알고 넘어가셔도 됩니다. 

C언어 초반에 배우는 이론들이 나중에 본격적으로 코드 쓰는 법을 배우면서 계속 코드를 쓰고 프로그램을 만들다 보면 다 이해가 가는 내용이라 처음부터 완벽하게 이해하실 필요는 없습니다. 

첨부터 무리하면 흥미 떨어지고 노잼되니깐요...ㅎㅎ

뒤에 가면 되게 재밌으니까 조금만 힘내서 지루한 초반부분을 넘어갑시다!

 


 

1. 형변환의 뜻은?

 

어떤 자료형으로 선언된 변수를 다른 자료형으로 바꾸는 것을 말합니다. 

예를 들면 int형 변수를 하나 만들었는데 그 변수를 float형으로 바꾸고 싶을 때 사용하는 것이죠. 

 

 

 

2. 암시적 형변환

 

#include<stdio.h>

void main()
{
	int num;
	float Fnum = 123.953;

	num = Fnum;
	printf("%d\n", num);
	Fnum = num;
	printf("%f\n", Fnum);

	printf("%f\n", Fnum + num);
	printf("%d\n", Fnum + num);
}

 

먼저 비주얼 스튜디오나 코드 블럭에 이렇게 코드를 적은 후 실행해봅시다.

더 나은 가독성을 위해 이렇게 올렸지만 코드를 그냥 복붙하는 것 보단 직접 따라서 쓰시는 것이 초반 공부에 도움됩니다. 

 

 

 

코드를 실행하면 이런 숫자들을 볼 수 있습니다. 

그런데 처음에 분명히 변수 Fnum에 소숫점 숫자를 넣어주고 자료형으로 %f를 썼는데 소숫점이 모두 0으로 출력되었습니다.

왤까요?

 

	int num;
	float Fnum = 123.953;

	num = Fnum;
	printf("%d\n", num);

비밀은 바로 여기에...

 

메인 함수의 시작에서 int형 변수 num을 만들고 

다음 줄에서 float형 변수 Fnum을 만들고 초기값으로 123.953을 넣어주었습니다. 

그러면 현재 num에는 초기값을 넣어주지 않았기 때문에 쓰레기값만 들어있습니다. 

그리고 Fnum엔 123.953이 들어있습니다. 

 

	num = Fnum;
	printf("%d\n", num);

그 다음 부분을 보면 num = Fnum;이라는 코드를 적었습니다. 

이것의 뜻은 변수 num 에 변수 Fnum의 값을 넣어라 라는 의미입니다. 

그래서 num에는 Fnum의 값인 123.953이 들어갔습니다. 

 

그런데 여기에서 작은 문제가 하나 생깁니다. 

 

num은 int형 변수이기 때문에 정수만 저장할 수 있고 그 외의 숫자나 문자는 저장할 수 없습니다. 

정수는 소숫점이 없는 숫자죠. 

그래서 num에 Fnum의 값 123.953을 넣었지만 int형 변수 num은 123 뒤의 소숫점 아래 숫자들은 저장할 수 없습니다. 

여기서 오류가 나면 노잼이었겠지만 다행히 오류가 나지는 않습니다. 

대신 소숫점 아래는 다 버리고 정수 부분만 저장합니다. 

그렇기 때문에 num은 123이 되었습니다. 

 

 

 

그래서 printf로 num을 출력했더니 123이 출력되었습니다. 

 

이런 식으로 다른 자료형 간에 정보를 저장할 때 컴퓨터가 알아서 자료형에 맞게 내용물을 바꿔서 저장해주는 것을 암시적 형변환이라고 합니다. 

대놓고 말하지 않아도 저렇게 쓰면 니가 알아서 바꿔라 이런 뜻을 간접적으로 표현하는 것이죠. 

그래서 암시적이라는 단어를 써서 표현하는 것 같습니다. 

 

여기까진 쉽죠?

그럼 다음 코드도 계속해서 보겠습니다. 

 

	Fnum = num;
	printf("%f\n", Fnum);

printf로 num을 출력한 다음 Fnum에 num이 가지고 있는 값을 넣어주었습니다. 

아까 num에 Fnum을 넣으면서 Fnum의 초기값이었던 123.953은 소숫점 아래가 사라지고 123이 되었습니다. 

그래서 Fnum엔 num이 가지고 있는 값인 123이 들어가게 되고 Fnum은 123이 되었습니다. 

 

 

 

 

그런데 Fnum은 소숫점을 저장하는 float형 변수니까 출력할 때도 서식문자 %f를 써서 출력하면 소숫점 아래가 출력은 되지만 맨 처음의 소숫점 아래 숫자들은 다 사라졌기 때문에 소숫점 아래엔 0만 출력됩니다. 

C 언어는 항상 메인함수의 윗 줄부터 차례대로 실행이 되거든요. 

윗 줄에서 변수의 값을 바꾸는 행동이 있었으면 다시 되돌아가서 처음 값으로 바꾸고 이런 행동은 하지 않습니다. 

한 번 바꼈으면 다시 바꿔주기 전 까지는 계속 바뀐 상태입니다. 

그래서 지금은 처음의 123.953에서 .953은 날아가고 123만 남아 있는 상태!

 

여기까지도 쉽죠?

 

	printf("%f\n", Fnum + num);
	printf("%d\n", Fnum + num);

이제 마지막으로 남은 코드 두 줄을 보면 Fnum과 num을 더한 값을 각각 float 자료형과 int 자료형으로 출력하고 있습니다. 

지금 Fnum과 num 둘 다 123을 가지고 있으니까 Fnum + num == 123 + 123 = 246 이네요. 

 

 

 

마지막 두 줄의 첫번째 줄에서 Fnum과 num을 더한 값을 %f를 사용해서 출력했기 때문에 246.000000 이 출력되었습니다. 

 

여기까진 쉽죠?

 

 

 

???

오잉 그런데 마지막 줄에서는 0이 출력되었습니다. 

윗 줄과 다른 것이라면 출력할 자료형으로 %d를 썼다는 것 뿐인데 말이에요. 

일반적인 상식으로는 마지막에도 246이 출력되어야 하잖아요. 

 

 

이것의 비밀은 바로....

 

자료형의 크기와 표현 범위의 차이에 있습니다. 

 

int형과 float 자료형 모두 크기는 4바이트로 동일하지만 표현 범위는 float형이 훨씬 넓습니다. 

자료형의 크기와 표현 범위가 크고 넓을수록 우선순위가 더 높다고 생각하시면 됩니다. 

암시적 형변환의 특징은 서로 다른 자료형 간에 연산이 생겼을 때에 결과값을 저장할 자료형을 지정해주지 않으면 무조건 우선순위가 더 높은 자료형으로 저장되는 것입니다. 

그렇기 때문에 컴퓨터는 서로 다른 자료형인 int와 float의 연산의 결과값은 둘 중 표현 범위가 더 넓은 float형으로 결과값을 저장한 것입니다.

그래서 마지막 줄에서 float보다 우선순위가 낮은 int형으로는 연산 결과값이 표현되긴 하는데 데이터 손실이 일어나서 다 날아가 버리고 0이 출력된 것입니다. 

우리가 컴퓨터에게 결과값을 저장할 자료형을 확실하게 알려주지 않고 니가 알아서 해 라고 한 결과가 이것이죠...

 

 

컴퓨터가 기준으로 삼는 자료형의 우선순위는 이렇습니다. 

 

char <  int < long int < unsigned int < float < double

 

 

char는 1바이트이고 double은 8바이트입니다. 

그렇기 때문에 가장 작은 char가 우선순위가 가장 낮고 가장 큰 double이 우선순위가 가장 높습니다. 

데이터 크기가 작은 것을 큰 것으로 표현할 때엔 데이터 손실이 일어나지 않지만 

큰 것을 작은 것으로 표현할 때엔 데이터 손실이 생깁니다. 

 

그래서 가장 좋은 것은 형변환을 할 일이 있으면 우선순위에 따라 처리를 하는 것이지만 사실 쓸 일이 별로 없어요...

전체 우선순위를 외울 필요도 없고(이것도 하다 보면 자연스럽게 습득 됩니다.) int와 float의 우선순위 정도만 기억하시면 좋습니다. 

그리고 컴퓨터가 생각만큼 어마무시하게 완벽하지는 않다는 것도...

 

 

 

3. 명시적 형변환

 

#include<stdio.h>

void main()
{
	int num;
	float Fnum = 123.953;

	num = Fnum;
	printf("%d\n", num);
	Fnum = num;
	printf("%f\n", Fnum);

	printf("%f\n", Fnum + num);
	printf("%d\n", (int)Fnum + num);
}

이번엔 이렇게 코드를 수정하고 실행해봅시다. 

아까 코드랑 비교해서 다른 점만 수정하면 되기 때문에 아까전에 썼던 코드를 모두 지우고 처음부터 작성하실 필요는 없습니다. 

 

 

 

 

아까랑 같지만 마지막 줄에선 0이 아닌 246이 출력되었습니다. 

아까 코드랑 비슷해 보이는데 달라진 점이 무엇일까요?

 

 

	printf("%d\n", (int)Fnum + num);

마지막 줄 빼고는 아까 썼던 코드랑 같으니까 마지막만 보겠습니다. 

 

아까처럼 Fnum과 num의 합을 %d를 사용해서 정수로 출력하는데 Fnum + num 앞에 (int)라고 적어주었습니다. 

이렇게 적어주면 이번 연산을 하는 순간에만 float형인 Fnum을 int형 숫자로 바꾸겠다는 뜻입니다.
이번 코드 줄에서만 float-> int 형으로 형변환을 해 주겠다는거죠.

다른 자료형으로 바꿔주려면 괄호 안에 해당하는 자료형을 적어주면 됩니다.

 

아까 전과 다르게 자료형을 확실하게 바꿔서 계산하라고 미리 알려주었기 때문에 컴퓨터가 이번엔 말귀를 제대로 알아듣고 우리가 생각하는 정상적인 결과값을 표시한 것이죠. 

 

이것이 바로 명시적 형변환입니다. 

 

별 거 없죠?

ㅎㅎ

 

 

두 종류의 형변환 중 명시적 형변환을 통해 우리가 원하는 결과값을 제대로 얻어낼 수 있었습니다.

그래서 형변환을 할 일이 생기면 명시적 형변환을 하는 것이 좋습니다. 

암시적 형변환은 실수할 가능성이 많으니까요. 

 

오늘의 포인트는 명시적 형변환을 사용하자!

다음엔 프로그램 실행 후 사용자에게서 값을 입력받고 저장할 수 있는 함수인 scanf에 대해 알아보겠습니다. 

다음에 만나요~

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함