변수(variable)
변수(variable)란 데이터(data)를 저장하기 위해 프로그램에 의해 이름을 할당받은 메모리 공간을 의미합니다.
즉, 변수란 데이터(data)를 저장할 수 있는 메모리 공간을 의미하며, 이렇게 저장된 값은 변경될 수 있습니다.
C++에서 숫자 표현에 관련된 변수는 정수형 변수와 실수형 변수로 구분할 수 있습니다.
또다시 정수형 변수는 char형, int형, long형, long long형 변수로, 실수형 변수는 float형, double형 변수로 구분됩니다.
관련된 데이터를 한 번에 묶어서 처리하는 사용자 정의 구조체 변수도 있습니다.
변수의 이름 생성 규칙
C++에서는 변수의 이름을 비교적 자유롭게 지을 수 있습니다.
변수의 이름은 해당 변수에 저장될 데이터의 의미를 잘 나타내도록 짓는 것이 좋습니다.
C++에서 변수의 이름을 생성할 때 반드시 지켜야 하는 규칙은 다음과 같습니다.
1. 변수의 이름은 영문자(대소문자), 숫자, 언더스코어(_)로만 구성됩니다.
2. 변수의 이름은 숫자로 시작될 수 없습니다.
3. 변수의 이름 사이에는 공백을 포함할 수 없습니다.
4. 변수의 이름으로 C++에서 미리 정의된 키워드(keyword)는 사용할 수 없습니다.
5. 변수 이름의 길이에는 제한이 없습니다.
C++에서는 변수의 이름에 대소문자를 구분하므로 이 점에 주의해야 합니다.
비트(bit)와 바이트(byte)
컴퓨터는 모든 데이터를 2진수로 표현하고 처리합니다.
비트(bit)란 컴퓨터가 데이터를 처리하기 위해 사용하는 데이터의 최소 단위입니다.
이러한 비트에는 2진수의 값(0과 1)을 단 하나만 저장할 수 있습니다.
바이트(byte)란 위와 같은 비트가 8개 모여서 구성되며, 한 문자를 표현할 수 있는 최소 단위입니다.
변수와 메모리 주소
변수는 기본적으로 메모리의 주소(address)를 기억하는 역할을 합니다.
메모리 주소란 물리적인 메모리 공간을 서로 구분하기 위해 사용되는 일종의 식별자입니다.
즉, 메모리 주소란 메모리 공간에서의 정확한 위치를 식별하기 위한 고유 주소를 의미합니다.
변수를 참조할 때는 메모리의 주소를 참조하는 것이 아닌, 해당 주소에 저장된 데이터를 참조하게 됩니다.
따라서 변수는 데이터가 저장된 메모리의 주소뿐만 아니라, 저장된 데이터의 길이와 형태에 관한 정보도 같이 기억해야 합니다.
변수의 선언
C++에서는 변수를 사용하기 전에 반드시 먼저 해당 변수를 저장하기 위한 메모리 공간을 할당받아야 합니다.
이렇게 해당 변수만을 위한 메모리 공간을 할당받는 행위를 변수의 선언이라고 부릅니다.
C++에서 변수를 선언하는 방법에는 다음과 같이 두 가지 방법이 있습니다.
1. 변수의 선언만 하는 방법
2. 변수의 선언과 동시에 초기화하는 방법
변수의 선언만 하는 방법
이 방법은 먼저 변수를 선언하여 메모리 공간을 할당받고, 나중에 변수를 초기화하는 방법입니다.
하지만 이렇게 선언만 된 변수는 초기화하지 않았기 때문에 해당 메모리 공간에는 알 수 없는 쓰레깃값만이 들어가 있습니다.
따라서 초기화하지 않은 변수는 절대로 사용해서는 안 됩니다.
문법
타입 변수이름;
예제
int num;
...
num = 20;
위의 예제처럼 정수를 저장하기 위한 메모리 공간을 할당받으면, 반드시 해당 타입의 데이터만을 저장해야 합니다.
그렇지 않고 다른 타입의 데이터를 저장할 경우에는 저장된 데이터에 변형이 일어날 수도 있습니다.
변수의 선언과 동시에 초기화하는 방법
C++에서는 변수의 선언과 동시에 그 값을 초기화할 수 있습니다.
또한, 선언하고자 하는 변수들의 타입이 같다면 이를 동시에 선언할 수 있습니다.
문법
1. 타입 변수이름[, 변수이름];
2. 타입 변수이름 = 초깃값[, 변수이름 = 초깃값];
예제
int num1, num2;
double num3 = 1.23, num4 = 4.56;
선언하고자 하는 변수의 타입이 서로 다르면 동시에 선언할 수 없습니다.
상수(constant)
상수(constant)란 변수와 마찬가지로 데이터를 저장할 수 있는 메모리 공간을 의미합니다.
하지만 상수가 변수와 다른 점은 프로그램이 실행되는 동안 메모리에 저장된 데이터를 변경할 수 없다는 점입니다.
표현 방식에 따른 상수
C++에서 상수는 표현 방식에 따라 다음과 같이 나눌 수 있습니다.
1. 리터럴 상수(literal constant)
2. 심볼릭 상수(symbolic constant)
리터럴 상수(literal constant)
리터럴 상수(literal constant)는 변수와는 달리 데이터가 저장된 메모리 공간을 가리키는 이름을 가지고 있지 않습니다.
C++에서는 적절한 메모리 공간을 할당받기 위하여, 기본적으로 변수든 상수든 타입을 가지고 있습니다.
C++에서 상수는 타입에 따라 정수형 리터럴 상수, 실수형 리터럴 상수, 문자형 리터럴 상수 등으로 구분할 수 있습니다.
1. 정수형 리터럴 상수는 123, -456과 같이 아라비아 숫자와 부호로 직접 표현됩니다.
2. 실수형 리터럴 상수는 3.14, -45.6과 같이 소수 부분을 가지는 아라비아 숫자로 표현됩니다.3. 문자형 리터럴 상수는 'a', 'Z'와 같이 따옴표('')로 감싸진 문자로 표현됩니다.
정수형 리터럴 상수
정수형 리터럴 상수는 123, -456과 같이 아라비아 숫자와 부호로 직접 표현됩니다.
C++에서는 정수형 상수를 10진수뿐만 아니라 8진수(0으로 시작)나 16진수(0x로 시작)로도 표현할 수 있습니다.
이렇게 여러 가지 진법으로 표현된 정수형 상수의 출력을 위해 cout 객체는 dec, hex, oct 조정자를 제공하고 있습니다.
이 세 가지 조정자를 cout 객체에 전달하면 사용자가 다시 변경하기 전까지 출력되는 진법의 형태를 계속 유지할 수 있습니다.
다음 예제는 숫자 10을 각각 10진수, 8진수, 16진수의 형태로 출력하는 예제입니다.
예제
int a = 10;
cout << "숫자 10을 10진수로 표현하면 " << a << "이며, " << endl;
cout << oct;
cout << "숫자 10을 8진수로 표현하면 " << a << "이며, " << endl;
cout << hex;
cout << "숫자 10을 16진수로 표현하면 " << a << " 입니다.";
정수형 리터럴 상수의 타입
C++에서 정수형 리터럴 상수는 다음과 같은 경우를 제외하면 모두 int형으로 저장됩니다.
1. 데이터의 값이 너무 커서 int형으로 저장할 수 없는 경우
2. 정수형 상수에 접미사를 사용하여, 해당 상수의 타입을 직접 명시하는 경우
C++에서는 접미사를 상수의 끝에 추가하여, 해당 상수의 타입을 직접 명시할 수 있습니다.
다음 표는 C++에서 접미사를 추가하여 나타낼 수 있는 정수형 타입을 나타냅니다.
접미사 |
타입 |
기본 설정 |
(signed) int형 |
u 또는 U |
unsigned int형 |
l 또는 L |
(signed) long형 |
ul 또는 uL 또는 Ul 또는 UL |
unsigned long형 |
long long 또는 u11 또는 U11 또는 uLL 또는 ULL |
unsigned long long형 (C++11부터 제공) |
실수형 리터럴 상수의 타입
C++에서 실수형 리터럴 상수는 모두 부동 소수점 방식으로 저장됩니다.
이러한 실수형 리터럴 상수는 모두 double형으로 저장되며, 접미사를 추가하여 저장되는 타입을 직접 명시할 수도 있습니다.
다음 표는 C++에서 접미사를 추가하여 나타낼 수 있는 실수형 타입을 나타냅니다.
접미사 |
타입 |
f 또는 F |
float형 |
기본 설정 |
double형 |
l 또는 L |
long double형 |
포인터 리터럴 상수
널 포인터(null pointer)란 아무것도 가리키고 있지 않은 포인터를 의미합니다.
지금까지 C++에서는 널 포인터를 표현하기 위해서 포인터를 0으로 초기화해 왔습니다.
하지만 C++11부터는 nullptr 키워드를 제공함으로써 0으로 초기화된 널 포인터보다 더욱 제대로 널 포인터를 표현할 수 있게 되었습니다.
nullptr 키워드를 사용한 리터럴 상수의 타입은 포인터 타입이며, 정수형으로 변환할 수 없습니다.
아직도 C++에서는 0을 사용해 널 포인터를 명시할 수 있으며, 따라서 nullptr == 0은 참(true)을 반환합니다.
하지만 nullptr 리터럴 상수를 사용하는 것이 좀 더 안전한 프로그램을 만들 수 있습니다.
이진 리터럴 상수
C++14부터는 0B 또는 0b의 접두사와 0과 1의 시퀀스를 가지고 이진 리터럴 상수를 표현할 수 있습니다.
예제
auto a = 0B010111;
심볼릭 상수(symbolic constant)
심볼릭 상수는 변수와 마찬가지로 이름을 가지고 있는 상수입니다.
심볼릭 상수는 선언과 동시에 반드시 초기화해야 합니다.
이러한 심볼릭 상수는 매크로를 이용하거나, const 키워드를 사용하여 선언할 수 있습니다.
하지만 매크로를 이용한 선언은 C언어의 문법이므로, C++에서는 가급적 const 키워드를 사용하여 선언하도록 합니다.
C++에서 심볼릭 상수를 만드는 일반적인 방식은 다음과 같습니다.
예제
const int ages = 30;
위의 예제처럼 const 키워드를 사용한 상수는 선언과 함께 반드시 초기화해야 합니다.
매크로를 이용한 선언보다 const 키워드를 사용한 심볼릭 상수의 장점은 다음과 같습니다.
1. 상수의 타입을 명시적으로 지정할 수 있습니다.
2. 구조체와 같은 복잡한 사용자 정의 타입에도 사용할 수 있습니다.
3. 해당 심볼릭 상수를 특정 함수나 파일에서만 사용할 수 있도록 제한할 수 있습니다.
기본 타입
타입(data type)이란 해당 데이터가 메모리에 어떻게 저장되고, 프로그램에서 어떻게 처리되어야 하는지를 명시적으로 알려주는 역할을 합니다.
C++에서는 여러 형태의 타입을 제공하고 있는데, 이것을 기본 타입이라고 합니다.
이러한 기본 타입은 크게 정수형, 실수형, 문자형 그리고 bool형 타입으로 나눌 수 있습니다.
정수형 타입
C++에서 정수란 부호를 가지고 있으며, 소수 부분이 없는 수를 의미합니다.
정수형 데이터에 unsigned 키워드를 추가하면, 부호를 나타내는 최상위 비트(MSB, Most Significant Bit)까지도 크기를 나타내는 데 사용할 수 있습니다.
unsigned 정수로는 음의 정수를 표현할 수는 없지만, 0을 포함한 양의 정수는 두 배 더 많이 표현할 수 있게 됩니다.
음의 정수까지도 표현할 수 있는 signed 키워드는 모든 타입에서 기본적으로 생략할 수 있습니다.
최상위 비트(MSB, Most Significant Bit)란 1바이트를 구성하는 8개의 비트 중 최고값을 갖는 비트를 의미합니다.
다음 표는 각각의 정수형 타입에 따른 메모리의 크기 및 데이터의 표현 범위를 나타냅니다.
정수형 타입 |
할당되는 메모리의 크기 |
데이터의 표현 범위 |
(signed) short |
2 바이트 |
-215 ~ (215 - 1) |
unsigned short |
2 바이트 |
0 ~ (216 - 1) |
(signed) int |
4 바이트 |
-231 ~ (231 - 1) |
unsigned int |
4 바이트 |
0 ~ (232 - 1) |
(signed) long |
4 바이트 |
-231 ~ (231 - 1) |
unsigned long |
4 바이트 |
0 ~ (232 - 1) |
unsigned long long |
8 바이트 |
0 ~ (264 - 1) |
정수형 데이터의 타입을 결정할 때에는 반드시 자신이 사용하고자 하는 데이터의 최대 크기를 고려해야 합니다.
타입이 표현할 수 있는 범위를 벗어난 데이터를 저장하면 오버플로우(overflow)가 발생해 전혀 다른 값이 저장될 수 있습니다.
오버플로우(overflow)란 해당 타입이 표현할 수 있는 범위를 넘는 데이터가 저장될 때 발생하는 현상을 가리킵니다.
오버플로우가 발생하면 최상위 비트(MSB)를 벗어난 데이터가 인접 비트를 덮어쓰므로, 잘못된 결과를 얻을 수 있습니다.
다음 예제는 int형 타입의 변수에 해당 타입이 저장할 수 있는 최댓값과 그 최댓값을 넘는 숫자를 대입하는 예제입니다.
예제
int num = 2147483647;
cout << "변수 num에 저장된 값은 " << num << "입니다." << endl;
num = 2147483648;
cout << "변수 num에 저장된 값은 " << num << "입니다." << endl;
위의 두 번째 실행 결과를 살펴보면, 변수 num에 양수를 대입했지만 음수로 저장된 것을 확인할 수 있습니다.
이처럼 오버플로우가 발생하면 전혀 예상치 못한 결과를 얻을 수 있으므로, 데이터를 저장할 때는 언제나 해당 데이터 타입의 최대 크기까지 고려해야 합니다.
컴퓨터는 내부적으로 정수형 중에서도 int형의 데이터를 가장 빠르게 처리합니다.
따라서 정수형 데이터는 보편적으로 int형을 가장 많이 사용합니다.
실수형 타입
C++에서 실수란 소수부나 지수가 있는 수를 가리키며, 정수보다 훨씬 더 넓은 표현 범위를 가집니다.
하지만 컴퓨터에서 실수를 표현하는 방식은 오차가 발생할 수 밖에 없는 태생적 한계를 지닙니다.
이러한 실수형 데이터의 오차는 C++뿐만 아니라 모든 프로그래밍 언어에서 발생하는 공통된 문제입니다.
실수형 타입 |
할당되는 메모리의 크기 |
데이터의 표현 범위 |
float |
4 바이트 |
(3.4 X 10-38) ~ (3.4 X 1038) |
double |
8 바이트 |
(1.7 X 10-308) ~ (1.7 X 10308) |
long double |
double형과 동일함. |
double형과 동일함. |
다음 예제는 소수점을 16자리 가지는 실수를 float 타입과 double 타입의 변수에 각각 대입하는 예제입니다.
예제
float num01 = 3.1415926535897932; // float 타입의 유효 자릿수는 소수점 6자리
cout << "변수 num01에 저장된 값은 " << num01 << "입니다." << endl;
double num02 = 3.1415926535897932; // double 타입의 유효 자릿수는 소수점 16자리
cout << "변수 num02에 저장된 값은 " << num02 << "입니다." << endl;
위의 예제에서 변수 num01에는 소수점 6자리까지만 정확한 값이 저장되어 있고, 소수점 7자리부터는 틀린 값이 저장되어 있습니다.
또한, 변수 num02에는 소수점 15자리까지만 정확한 값이 저장되어 있고, 소수점 16자리부터는 틀린 값이 저장되어 있는 것을 확인할 수 있습니다.
이처럼 실수형 데이터의 타입을 결정할 때에는 표현 범위 이외에도 유효 자릿수를 반드시 고려해야 합니다.
실수형 타입 |
지수의 길이 |
가수의 길이 |
유효 자릿수 |
float |
8 비트 |
23 비트 |
소수 부분 6자리까지 오차없이 표현할 수 있음. |
double |
11 비트 |
52 비트 |
소수 부분 15자리까지 오차없이 표현할 수 있음. |
과거에는 실수를 표현할 때 float형을 많이 사용했지만, 하드웨어의 발달로 인한 메모리 공간의 증가로 현재에는 double형을 가장 많이 사용합니다.
문자형 타입
C++에서 문자형 데이터란 작은 정수나 문자 하나를 표현할 수 있는 타입을 가리킵니다.
컴퓨터는 2진수밖에 인식하지 못하므로 문자도 숫자로 표현해야 인식할 수 있습니다.
따라서 어떤 문자를 어떤 숫자에 대응시킬 것인가에 대한 약속이 필요하게 됩니다.
이러한 약속 중에서 가장 많이 사용되는 것이 바로 아스키코드(ASCII)입니다.
아스키코드(ASCII)는 영문 대소문자를 사용하는 7비트의 문자 인코딩 방식입니다.
아스키코드는 문자를 7비트로 표현하므로 총 128개의 문자를 표현할 수 있습니다.
문자형 타입 |
할당되는 메모리의 크기 |
데이터의 표현 범위 |
(signed) char |
1 바이트 |
2-7 ~(27 - 1) |
unsigned char |
1 바이트 |
0 ~ 28 |
bool 형 타입
이전의 C++에서는 C언어와 마찬가지로 0인 값을 거짓으로, 0이 아닌 값을 참으로 인식했습니다.
하지만 C++11부터는 bool형이라는 새로운 타입을 제공하고 있습니다.
bool형은 참(true)이나 거짓(false) 중 한 가지 값만을 가질 수 있는 불리언 타입입니다.
C++에서는 어떤 값도 bool형으로 묵시적 타입 변환이 가능합니다.
이때 0인 값은 거짓(false)으로, 0이 아닌 값은 참(true)으로 자동 변환됩니다.
auto 키워드를 이용한 선언
C++11부터는 변수의 초기화 값에 맞춰 변수의 타입을 추론할 수 있습니다.
즉, 변수를 초기화할 때 특정 타입을 명시하는 대신에, auto 키워드를 사용하여 초깃값에 맞춰 타입이 자동으로 선언되도록 설정할 수 있습니다.
기존의 auto 키워드는 자동 저장소 클래스에 있는 지역 변수를 선언하는 데 사용되는 기억 클래스 지정자였습니다.
하지만 사용하는 의미가 거의 없었기 때문에 기존의 auto 키워드는 거의 사용되지 않았습니다.
하지만 C++11부터는 auto 키워드의 의미를 재정의하여, 변수 선언 시 초깃값과 같은 타입으로 변수를 선언할 수 있도록 해줍니다.
즉, auto 키워드를 사용하면 복잡한 형식의 변수를 간단하게 선언할 수 있습니다.
실수의 표현 방식
컴퓨터에서 실수를 표현하는 방법은 정수에 비해 훨씬 복잡합니다.
왜냐하면, 컴퓨터에서는 실수를 정수와 마찬가지로 2진수로만 표현해야 하기 때문입니다.
따라서 실수를 표현하기 위한 다양한 방법들이 연구되었으며, 현재에는 다음과 같은 방식이 사용되고 있습니다.
1. 고정 소수점(fixed point) 방식
2. 부동 소수점(floating point) 방식
고정 소수점(fixed point) 방식
실수는 보통 정수부와 소수부로 나눌 수 있습니다.
따라서 실수를 표현하는 가장 간단한 방식은 소수부의 자릿수를 미리 정하여, 고정된 자릿수의 소수를 표현하는 것입니다.
하지만 이 방식은 정수부와 소수부의 자릿수가 크지 않으므로, 표현할 수 있는 범위가 매우 적다는 단점이 있습니다.
부동 소수점(floating point) 방식
실수는 보통 정수부와 소수부로 나누지만, 가수부와 지수부로 나누어 표현할 수도 있습니다.
부동 소수점 방식은 이렇게 하나의 실수를 가수부와 지수부로 나누어 표현하는 방식입니다.
앞서 살펴본 고정 소수점 방식은 제한된 자릿수로 인해 표현할 수 있는 범위가 매우 작습니다.
하지만 부동 소수점 방식은 다음 수식을 이용하여 매우 큰 실수까지도 표현할 수 있습니다.
수식
±(1.가수부)×2지수부-127
현재 대부분의 시스템에서는 부동 소수점 방식으로 실수를 표현하고 있습니다.
C++ 부동 소수점 표현 방식
C++에서는 부동 소수점을 다음 두 가지 방식으로 표현할 수 있습니다.
1. 3.14, -45.6과 같이 소수 부분을 가지는 아라비아 숫자로 표현합니다.
2. e 또는 E를 사용하여 지수 표기법으로 표현합니다.
IEEE 부동 소수점 방식
현재 사용되고 있는 부동 소수점 방식은 대부분 IEEE 754 표준을 따르고 있습니다.
부동 소수점 방식의 오차
부동 소수점 방식을 사용하면 고정 소수점 방식보다 훨씬 더 많은 범위까지 표현할 수 있습니다.
하지만 부동 소수점 방식에 의한 실수의 표현은 항상 오차가 존재한다는 단점을 가지고 있습니다.
부동 소수점 방식에서의 오차는 앞서 살펴본 공식에 의해 발생합니다.
이 공식을 사용하면 표현할 수 있는 범위는 늘어나지만, 10진수를 정확하게 표현할 수는 없게 됩니다.
따라서 컴퓨터에서 실수를 표현하는 방법은 정확한 표현이 아닌 언제나 근사치를 표현할 뿐임을 항상 명심해야 합니다.
다음 예제는 부동 소수점 방식으로 실수를 표현할 때 발생할 수 있는 오차를 보여주는 예제입니다.
예제
int i;
float sum = 0;
for (i = 0; i < 1000; i++)
{
sum += 0.1;
}
cout << "0.1을 1000번 더한 합계는 " << sum <<"입니다.";
위의 예제에서 0.1을 1000번 더한 합계는 원래 100이 되어야 하지만, 실제로는 99.999가 출력됩니다.
이처럼 컴퓨터에서 실수를 가지고 수행하는 모든 연산에는 언제나 작은 오차가 존재하게 됩니다.
이것은 C++뿐만 아니라 모든 프로그래밍 언어에서 발생하는 기본적인 문제입니다.
타입 변환(type conversion)
C++에서 다른 타입끼리의 연산은 우선 피연산자들을 모두 같은 타입으로 만든 후에 수행됩니다.
이처럼 하나의 타입을 다른 타입으로 바꾸는 행위를 타입 변환(type conversion)이라고 합니다.
C++에서는 다음과 같은 경우에 자동으로 타입 변환을 수행합니다.
1. 다른 타입끼리의 대입, 산술 연산 시
2. 함수에 인수를 전달할 때
이때 표현 범위가 좁은 타입에서 표현 범위가 더욱 넓은 타입으로의 타입 변환은 큰 문제가 되지 않습니다.
하지만 반대의 경우처럼 표현 범위가 좁은 타입으로의 타입 변환은 데이터의 손실이 발생합니다.
타입 변환의 종류
C++에서 타입 변환은 크게 다음과 같이 두 가지 방식으로 나뉩니다.
1. 묵시적 타입 변환(자동 타입 변환)
2. 명시적 타입 변환(강제 타입 변환)
묵시적 타입 변환(자동 타입 변환)
묵시적 타입 변환은 대입 연산이나 산술 연산에서 컴파일러가 자동으로 수행해주는 타입 변환을 가리킵니다.
C++에서는 대입 연산 시 연산자의 오른쪽에 존재하는 데이터의 타입이 연산자의 왼쪽에 존재하는 데이터의 타입으로 묵시적 타입 변환이 진행됩니다.
산술 연산 시에는 데이터의 손실이 최소화되는 방향으로 묵시적 타입 변환이 진행됩니다.
다음 예제는 대입 연산에서 일어나는 묵시적 타입 변환을 보여줍니다.
예제
int num1 = 3.1415;
int num2 = 8.3E12;
double num3 = 5;
cout << "num1에 저장된 값은 " << num1 << "입니다." << endl;
cout << "num2에 저장된 값은 " << num2 << "입니다." << endl;
cout << "num3에 저장된 값은 " << num3 << "입니다.";
위의 예제에서 첫 번째 연산은 int형 변수에 실수를 대입하므로 소수 부분이 자동으로 삭제되어 데이터의 손실이 발생합니다.
두 번째 연산에서는 int형 변수가 저장할 수 있는 최대 범위를 초과한 데이터를 저장하므로 전혀 알 수 없는 결과가 출력됩니다.
하지만 세 번째 연산에서는 범위가 큰 double형 변수에 범위가 작은 int형 데이터를 대입하므로 전혀 문제가 되지 않습니다.
다음 예제는 산술 연산에서 일어나는 묵시적 타입 변환을 보여줍니다.
예제
double result1 = 5 + 3.14;
double result2 = 5.0f + 3.14;
cout << "result1에 저장된 값은 " << result1 << "입니다." << endl;
cout << "result2에 저장된 값은 " << result2 << "입니다.";
위의 예제에서 첫 번째 연산은 int형 데이터와 double형 데이터의 산술 연산입니다.
따라서 데이터의 손실이 최소화되도록 int형 데이터가 double형으로 자동 타입 변환됩니다.
두 번째 연산은 float형 데이터와 double형 데이터의 산술 연산입니다.
위와 마찬가지로 데이터의 손실이 최소화되도록 float형 데이터가 double형으로 자동 타입 변환됩니다.
이렇게 컴파일러가 자동으로 수행하는 타입 변환은 언제나 데이터의 손실이 최소화되는 방향으로 이루어집니다.
따라서 C++에서는 다음과 같은 방향으로 자동 타입 변환이 이루어집니다.
char형 → short형 → int형 → long형 → float형 → double형 → long double형
산술 연산 시 bool형 데이터인 true는 1로, false는 0으로 자동 타입 변환됩니다.
명시적 타입 변환(강제 타입 변환)
명시적 타입 변환은 사용자가 타입 캐스트(cast) 연산자를 사용하여 강제적으로 수행하는 타입 변환을 가리킵니다.
C++에서는 다음 두 가지 방식으로 명시적 타입 변환을 수행할 수 있습니다.
문법
1. (변환할타입) 변환할데이터 // C언어와 C++ 둘 다 사용 가능함.
2. 변환할타입 (변환할데이터) // C++에서만 사용 가능함.
변환시키고자 하는 데이터나 변수의 앞과 뒤에 괄호(())를 붙이고, 그 괄호 안에 변환할 타입을 적으면 됩니다.
C++에서는 이 괄호를 타입 캐스트(type cast) 연산자라고 합니다.
다음 예제는 명시적 타입 변환을 보여주는 예제입니다.
예제
int num1 = 1;
int num2 = 4;
double result1 = num1 / num2;
double result2 = (double) num1 / num2;
double result3 = double (num1) / num2;
cout << "result1에 저장된 값은 " << result1 << "입니다." << endl;
cout << "result2에 저장된 값은 " << result2 << "입니다." << endl;
cout << "result3에 저장된 값은 " << result3 << "입니다.";
위의 예제에서 첫 번째 연산의 결괏값은 0으로 출력됩니다.
그 이유는 산술 연산에 대한 결괏값의 타입은 언제나 피연산자의 타입과 일치하기 때문입니다.
즉, int형 데이터끼리의 산술 연산에 대한 결괏값은 언제나 int형 데이터로 나오게 됩니다.
따라서 두 번째 연산에서처럼 하나의 피연산자를 명시적으로 double형으로 변환해야만 정확한 결괏값을 얻을 수 있습니다.
세 번째 연산은 C++에서만 사용할 수 있는 명시적 타입 변환 스타일의 사용법을 보여주고 있습니다.
댓글