C언어 > 데이터 형변환

TODAY201 TOTAL2,275,310
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

아두이노 센서 ATMEGA128 PWM LED 초음파 AVR 블루투스 LCD UART 모터 적외선


BASIC4MCU | C언어 | C언어 | 데이터 형변환

페이지 정보

작성자 키트 작성일2017-09-12 13:04 조회1,723회 댓글0건

본문

 

[C언어강의 #7] 형 변환 (Type Conversion), 주석 (Comment)

C Language냥초 2012/07/19 03:16

오늘은 C언어 뿐만이 아니라 여타 고급 언어(High-level Language)에서 중요한 (지금까지 써왔던 내용들도 중요하지만) 개념인 형 변환(Type Conversion)에 대해 강의하고자 한다. 

오늘의 강의도 강의 #2 [ 자료형과 변수 ]의 내용이 바탕이 되어 있으면 더욱 이해하기 쉬울 것이다.


1. 형 변환 (Type Conversion)?


가령, float형 변수에 2.5가 들어있다고 치자. 여기에 정수형으로 입력받은 값을 바탕으로 더하거나 빼고싶다. 즉, myFloat + myInt; 라는 식이 있다고 하자. 이전 강의에서 분명 정수형과 실수형은 저장되는 메커니즘이 다르다고 했다. 같은 자료형이면 덧셈이나 뺄셈이 용이하다. 형식이 동일하기 때문에 bit 끼리 더하거나 빼주는 2진 연산을 수행하면 되기 때문이다. 그런데 이와 같이 자료형이 다른 경우는 어떻게 될 것인가? 에러처리?

더 나아가서, myDouble + myChar; 의 값은 어떻게 계산하나? "3.141592에 알파벳 A를 더하라"와 같은 이뭐병 장애인같은... 쉽지 않은 연산이 왔을 때, 어떻게 될 것인가? (결론부터 말하자면 일단 이 식도 되긴 된다). 이럴 때 사용하는 것이 형 변환(Type Conversion)이다.

쉽게 말하자면, 하나의 형을 다른 형으로 변환하는 것인데 여기에는 두 가지의 종류가 있으며, 두 가지의 방법이 있다. (뭐야 이거 몰라 무서워....) 하나하나 알아보자.



2. 형 변환의 두 가지 방법

2-1) 묵시적 형변환 (Implicit type conversion)

 컴파일러에 의해 자동으로 행해지는 형 변환이다. 주로 "수식에서 데이터형이 혼합되어 사용되었을 때, 값 변환" 과, "특정 변수에 다른 형의 값이나 변수를 대입할 때" 컴파일러가 그 중간과정에서 형 변환을 알아서 적절히 해주어서, 문제가 없게(?) 하는 것이다.

 가령 위에서 말한 myFloat = myFloat + myInt; 라는 표현식에서, 정수형이 실수형으로 형 변환이 자동으로 일어나게 된다.
 특정 변수에 다른 형의 값을 대입하는 것은 다음과 같은 표현식이다.

 myFloat = 3; (3은 정수형이다. 원래 정확한 표현은 myFloat = 3.0f; 이다. myFloat = 3.0; 의 경우, 3.0은 double형이므로 역시 형변환이 일어나게 된다)

 이것은 그냥 컴파일러에 의해 자동으로 되므로 별 생각없이 그냥 쓰면 된다. 그러나 추천하지는 않는다.


2-2) 명시적 형변환 (Explicit type conversion)

 프로그래머가 형 변환자(cast)를 사용하여 강제적으로 형변환을 하게 하는 경우이다. ()와 소괄호 속에 변환하고자 하는 타입을 적는다. (int)myFloat; 혹은 (float)myInt; 와 같이 식 앞에 적어주면 된다.




3. 형 변환의 두 가지 형태

먼저, 변환 계급 (Conversion Rank)에 대해 언급하자. 각 타입에 계급을 부여하는 것이다.

845

잘 보면, bit를 많이 사용할 수록, 높은 계급 값을 가지고 있는 것을 알 수 있다.

Boolean - 1 bit
Char - 8 bits
int - 32 bits
double - 64 bits

여기서 두 가지의 형 변환이 일어날 수 있는데, 하나는 상위 랭크로의 형변환이며, 하나는 하위 랭크로의 형변환이다. 
이를 형 확장(Promotion), 형 축소(Demotion)? 라고 한다. 즉, (float)myInt는 형 확장, (int)myDouble은 형 축소가 되는 것이다.

형 확장은 문제가 거의 되지 않는다만, 형 축소에는 많은 문제가 따르게 된다. 이는 처음에도 말했듯이, 저장방식의 차이가 있기 때문인데, 다음과 같은 형 확장과 형 축소를 생각해보자.

char myChar = 'A'; ('A'는 65라는 숫자의 값을 나타낸다. 외우고 있자)
int myInt = 512;
int res_Int;
char res_Char;


(1) res_Int = (int) myChar;
(2) res_Char = (char) myInt;



(1) myChar ( 01000001₂를 int형 변수 res_Int에 저장할 때, 복사되는 모습 )
 보는 것과 같이, 상위 비트는 0으로 모두 채워지기 때문에, 결과 값은 원하는 대로 보존된다.

846


(2) myInt ( 1000000000₂를 char형 변수 res_Char에 저장할 때, 복사되는 모습)
 보는 것과 같이, 하위 8비트를 제외하고, 모든 비트가 사라진다. 만약, 윗 비트가 모두 0이라면 결과 값은 동일하겠지만, 보는 것과 같이 0이 아닌 것이 있다면, 이 비트들은 증발한다. 즉, 오차가 생긴다.

848

즉, 범위가 큰 형에서 작은 형으로 갈 때는, 데이터 손실이 일어날 수 있다. 다음은 대표적인 데이터 손실의 예이다.

● double -> float : 소수의 정밀도(소수점 아래 자리수)에서 차이가 난다. float은 대략 소수점 6자리, double은 15자리 정도 표현할 수 있기에 소수점 7번째 자리부터 데이터 손실이 일어난다고 보면 된다.

● float(혹은 double) -> int : 소수 부분을 잃어버린다. 이것을 활용하여 실수에서 정수 부분과 소수 부분을 쉽게 분별할 수 있다.

● int -> char : 위에서 적힌 대로 0~255의 값만 취할 수 있기 때문에, 그 이상의 값들은 제대로 표현되지 않는다. (int형 값을 256으로 나눈 나머지를 표현하고 있다고 보면 된다)



※ 묵시적 형변환과 명시적 형변환의 차이점

다음과 같은 코드를 고려하자. 우선 f1은 묵시적 형변환, f2는 명시적 형변환을 사용하고 있다. 3과 2는 둘 다 정수형이다.

315

결과는 f1, f2 모두 1.5 라는 결과를 예측하고 프로그램을 작성한 것이다. 이 프로그램의 결과는 다음과 같다.


677
왜 이럴까? 답은 다음과 같은 과정에 의해 차이가 나게 된다.

● f1 = 3/2; 의 경우
(1) 3과 2는 모두 int형 이므로 계산 결과도 형 변환 없이 int형이 된다. 3/2의 값은 1.5이며, int형 결과에 실수형 연산값 1.5를 넣어야 하므로 소숫점 결과를 제외하고 1이라는 결과값을 갖는다. [ 이전 강의에서 모든 표현식은 결과값을 갖는다고 하였다 ]

(2) 결과값 1(integer)을 f1이라는 float형 변수에 대입하는 형태이므로, 컴파일러에 의해 묵시적 형변환이 일어나고, f1에는 1.0이 저장된다.


● f2 = (float) 3/2; 의 경우
(1) 위와 동일하게 1.5의 값을 가진다. 그러나 형 변환 연산자 float에 의해 결과값의 타입이 int형에서 float형으로 형변환이 일어나서, 1.5가 그대로 결과값에 저장된다.

댓글 0

조회수 1,723

등록된 댓글이 없습니다.

C언어HOME > C언어 > C언어 목록

게시물 검색

2022년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2021년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2020년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2019년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2018년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
Privacy Policy
MCU BASIC ⓒ 2020
모바일버전으로보기