일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- CS
- Tips강좌
- Programming
- 리뷰
- 함수
- 지식나눔강좌
- Javascript
- tipssoft
- 문법
- 이지스퍼블리싱
- 백준
- doit코틀린프로그래밍
- VS ERROR
- 김성엽
- 티스토리
- Desktop
- 프로그래밍
- Visual Studio
- 알고리즘
- Direct2D
- Kotlin
- 포인터
- Win32
- c++
- c#
- 배열
- Tips프로그래밍강좌
- 연산자
- c
- Windows
- Yesterday
- Today
- Total
F.R.I.D.A.Y.
숫자의 형변환 본문
C언어는 다양한 자료형이 있습니다. 서로 다른 두 자료형을 연산해주기 위해서는 어느 한 자료형을 다른 자료형으로 형변환(캐스팅, casting) 해주어야 연산을 진행할 수 있습니다. 오늘은 자료형, 특히 숫자 자료형의 형변환에 대해 알아보겠습니다.
상수의 기본형
형변환을 알아보기 전에 숫자 상수의 기본 타입을 알아야합니다. C언어에서 숫자라 함은 일반적으로 정수(char, short, int 등)와 실수(float, double 등)로 나누게 됩니다.
첫 순서로 정수형 상수의 타입을 알아봅시다.
char ch1 = 65;
short wch1 = 300;
int var1 = 900;
int var2 = 12'000; // 숫자가 길면 이렇게 홑따옴표(')로 구분할 수 있습니다.
이 상수들의 타입은 무엇일가요? ch1은 char, wch1 = short, var1 = int, var2 = int입니다. 물론 변수는 그 타입을 알아보기가 쉽지만, 이들 {65, 300, 900, 12'000}의 타입은 무엇일까요? int입니다. 따로 접미어나 캐스팅을 진행하지 않았을 때 기본 타입은 int로 설정됩니다.
이제보니 정수 상수 자체는 모두 int타입으로 되어있네요.
실수의 경우 기본적으로 double을 자료형으로 가집니다. 이러한 기본 자료형의 특성으로 인해 접미어, 명시적 형변환을 해주지 않으면 표현가능한 범위는 int, double의 범위를 가집니다.
암시적 형변환
처음, 자료형이 다른 두 피연산자를 연산할 때는 어느 하나를 다른 하나의 자료형 타입으로 형변환 해주어야 한다고 했습니다. 그렇다면 모든 경우에 대해 개발자가 일일이 형변환을 해주어야할까요? 아닙니다. 연산자가 다른 피연산자를 컴파일 하게 되면 컴파일러는 두 피연산자를 평가하여 좀 더 범위가 큰 자료형을 수정을 하여 연산을 합니다. 즉, 아래 표와 같이 연산이 진행됩니다.
연산식 | 결과 |
char + short | short |
char + int | int |
int + short | int |
char + float | float |
float + double | double |
int + double | double |
이를 암시적 형변환이라고 합니다. 정수와 실수가 연산이 되면 정수가 실수처리되어 연산이 이루어집니다. 즉, 평가하는 두 값 중 더 큰 값에 맞추어 자동으로 캐스팅이 이루어지는 것을 암시적 형변환이라고 합니다. 암시적 형변환은 개발자를 편하게하는 문법이기도 하지만 제대로 사용하지 않으면 오히려 논리적 오류를 낼 수 있는 독이 될 수 있음을 인지해두세요.
명시적 형변환
암시적 형변환이 있다면, 명시적 형변환도 있습니다. C에서는 형변환 하고자 하는 대상 앞에 "(자료형)"을 붙여 형변환을 하는데요, 예시 코드는 아래와 같습니다.
char a = (char)12;
float b = (float)14;
int c = (int)123.123;
형변환에 사용할 수 있는 자료형으로는 언어에서 자체적으로 지원하는 int, double과 같은 빌트인(Built-in Data-type) 자료형뿐만 아니라 사용자가 직접 정한 사용자 지정 자료형(User-defined Data-type)으로도 캐스팅 할 수 있습니다.
암시적 자료형보다는 복잡하고 작성해야 하는 부분들이 더 많기 때문에 귀찮은 것은 사실이지만, 데이터를 원하는대로 캐스팅해 사용할 수 있고 변경될 자료형이 눈에 보이므로 논리적 오류를 덜 발생시킵니다.
※ 빌트인 자료형과 사용자 지정 자료형에 대해서는 링크의 7번 항목을 참고하세요.
자주하는 실수
암시적 형변환이 독이 될 수 있다고 말씀드린 것처럼 발생할 수 있는 문제가 하나 있습니다. 일반적으로 1/2는 무엇인가요? 0.5입니다. 그러나 컴퓨터 연산(C/C++)을 진행하면 1/2는 0이 결과(-1/2 또한 결과 0)가 됩니다. 이 때문에 실수로 0.5가 반환될것이라고 믿고 이렇게 작성을 하게 되면 결과값이 제대로 나오지 않는 문제가 발생합니다.
// 이 코드를 실행하면 test값은 0.5가 나올것 같지만 실제로는 0이 됩니다.
#include <stdio.h>
int main(void) {
float test = 1/2;
printf("%f", test);
return 0;
}
이 코드에서 1/2가 0.5가 나오도록 하기 위해서는 다음과 같이 작성해야합니다.
// 아래 코드 중 한 가지를 선택할 수 있습니다.
// 이 외에도 더 많이 있습니다.
float test = 1/2.0;
float test = 1.0/2;
float test = (float)1/2;
float test = 1/(float)2;
float test = (double)1/2;
float test = 1/(double)2;
이러한 문제는 각 언어마다 차이를 두고 있기 때문에 다른 언어, 대표적으로 파이썬의 경우에는 0.5 정상적으로 나오게 됩니다. 형변환은 언어의 특성을 타기 때문에 본인이 사용하는 언어가 어떤 식으로 연산을 처리하는지 인지하고 있어야합니다.
# index
'DEV > C C++' 카테고리의 다른 글
상수의 접미어 (0) | 2019.04.13 |
---|---|
예외처리 - assert 사용해보기 (0) | 2019.04.12 |
변수 초기화 (0) | 2019.04.06 |
부동소수점은 ==으로 비교하지 마세요 (6) | 2019.04.05 |
C/C++ 표준 코드(main 함수 표준) (0) | 2019.03.25 |