C++는 기본적인 계산(덧셈, 뺄셈, 곱셈, 나눗셈, 나머지셈)을 위해 다섯 가지 연산자를 제공한다. 각각의 연산잔느 연산의 대상으로 삼을 두 개의 값을 필요로 한다. 이를 피연산자라 한다.
int wheels = 4 + 2;
위의 코드는 값 4와 2가 피연산자이다.
기호 | 예시 | 설명 |
+ | A + B | A와 B를 더한다. |
- | A - B | A에서 B를 뺀다. |
* | A * B | A와 B를 곱한다. |
/ | A / B | A에서 B를 나눈다. |
% | A % B | A에서 B를 나누어 나머지를 구한다. |
연산 순서: 우선순위와 결합 방향
C++에는 하나의 피연산자에 하나 이상의 연산자가 걸렸을 때 어느 연산자를 먼저 적용할 것인지 결정하는 운선순위 규칙이 있다.
산술 연산자는 일반 대수학의 우선순위 규칙을 따른다. 즉, 곱셈, 나눗셈, 나머지셈은 덧셈과 뺄셈보다 먼저 계산한다. 덧셈과 뺄셈은 우선순위가 같고, 곱셈, 나눗셈, 나머지셈은 우선순위가 같다.
int num = 3 + 4 * 5;
num은 35가 아닌 23이 된다. 물론 괄호를 사용하여 우선순위를 바꿀 수 있다.
우선순위가 같은 연산자의 경우 순서가 어떻게 될까?
int num = 120 / 4 * 5;
우선순위가 같은 경우 왼쪽에서 오른쪽으로 계산한다. num은 150이 된다.
나눗셈에 대한 보충
나눗셈 연산자는 피연산자의 데이터형에 따라 결과가 달라진다. 만약 두 피연산자 모두 정수형이라면 정수 나눗셈을 수행한다. 즉, 결과의 소수부를 버리고 정수로 만든다.
int num = 10 / 4; //2.5가 아닌 2가 대입된다.
피연산자가 하나라도 부동 소수점수라면 결과는 부동 소수점수가 된다.
나머지셈 연산자
나머지셈은 나눗셈의 나머지를 리턴한다. 정수 나눗셈은 나머지 값을 모두 버리므로 정수 나눗셈과 함께 사용하면 유용하다.
int main()
{
using namespace std;
int num = 34;
cout << "10의 자리수 : " << num / 10 << endl;
cout << "1의 자리수 : " << num % 10 << endl;
system("Pause");
return 0;
}
데이터형 변환
C++의 데이터형은 종류가 많아서 컴퓨터의 처리는 복잡해진다. 데이터형을 혼합하여 사용하면 C++는 데이터형의 불일치를 해결하기 위해 다으모가 같은 상황에서 자동으로 데이터형 변환을 수행한다.
- 특정 데이터형의 변수에 다른 데이터형의 값을 대입했을 때
- 수식에 데이터형을 혼합하여 사용했을 때
- 함수에 매개변수를 전달할 때
C++에서는 어떤 데이터형의 값을 다른 데이터형이 변수에 대입하는 것이 자유롭다.
short thirty = 10;
long so_long = thirty; //long형에 short형 대입
위 경우 처럼 상대적으로 작은 데이터형의 값을 상대적으로 큰 데이터형에 대입하는 것은 문제가 되지 않는다. 하지만 반대의 경우는 문제가 생길 수 있다.
데이터형 변환 | 잠재적인 문제점 |
double → float (큰 부동 소수점형을 작은 부동 소수점형) | 정밀도(유효 숫자)가 손실된다. 원래 값이 변환 데이터형의 범위를 벗어날 경우, 결과를 예측할 수 없다. |
float → int (부동 소수점형을 정수형) | 소수부를 잃어버린다. 원래 값이 변환 데이터형의 범위를 벗어날 경우, 결과를 예측할 수 없다. |
long → short (큰 정수형을 작은 정수형으로) | 원래 값이 변환 데이터형의 범위를 벗어날 경우, 대개 하위 바이트들만 복사된다. |
C++는 어떤 수식의 값을 평가할 때 bool, cahr, unsigned char, signed char, short형 모두 int형으로 변환된다. 이러한 변환을 정수 승급(integral promotion)이라 한다. 컴퓨터가 int형에 대해 가장 빠르게 계산을 수행한다는 말이 이 때문이다.
short chicken = 20;
short ducks = 35;
short fowl = chickens + ducks;
세 번째 행의 구문을 실행하기 위해, C++은 chickens와 ducsk의 값을 int형으로 각각 변환한 후 더하고, short형으로 다시 변환한다.
이와 반대로 부동소수점형의 경우 얘기가 달라진다. 정수형과 부동 소수점의 연산은 부동 소수점형으로 변환되어 계산한다. 다음은 C++11 버전에서 컴파일러가 검사를 진행하는 순서이다.
- 한쪽 피연산자가 부동 소수점형이면, 해당 부동 소수점형으로 변환한다.
- 피연산자들이 모두 부동 소수점형이 아니라면, 정수형이므로 정수 승급이 일어난다.
- 정수 승급이 일어난 경우, 양쪽 피연산자가 모두 signed이거나, 모두 unsinged일 경우 두 피연사자의 상대적 크기에 따라 큰 쪽으로 변환한다.
- 두 피연산자의 signed, unsigned가 다를 경우, 상대적으로 큰 피연산자형으로 변환한다.
- signed형이 unsinged형의 모든 값을 표현할 수 있다면, unsigned 피연산자가 signed형으로 변환된다.
- 지금까지 해당되지 않을 경우, 양쪽 피연산자 모두 signed형의 unsigned형으로 변환된다.
C++에서는 데이터형 변환자를 사용하여 강제로 데이터형을 변환시킬 수 있다. 간단하게 사용할 경우 두 가지가 있다.
(long) thorn; //C에서 부터 사용한 캐스팅
long (thorn); //C++에서 추가된 캐스팅
또한 C++는 좀 더 사용이 제한적인 네 개의 데이터형 변환 연산자가 추가되었다.
종류 | 기능 |
static_cast | 기존 캐스팅과 같은 기능 |
dynamic_cast | 런타임에 상속 계층 관계를 가로지르거나, 다운 캐스팅 |
const_cast | 상수성 추가/제거 |
reinterpret_cast | 어떠한 포인터 타입도 어떠한 포인터 타입으로든 변환 |
C++11에서의 auto 선언
C++11은 초기화하는 값을 보고 변수형을 추론할 수 있다. 그러기 위해 auto의 의미를 재정의하고 있다.
auto n = 100; //n은 int형
auto x = 1.5; //x는 double형
auto y = 1.3e12L; //y는 long double형
편리해 보이지만 auto를 남발하면 문제가 발생할 수 있다. 다중프로세서 컴파일시 순서를 알 수 없이 컴파일하기 때문에 어떤 자료형인지 알 수 없은 경우가 생기면 문제가 발생한다.
auto x = 0.0; //0.0이 double형이므로 x는 double형
double y = 0; //y는 double형이므로 0이여도 문제 없음
auto z = 0; //0은 int이므로 z는 int형
auto는 복잡하고 긴 변수형을 다룰 때 유용하다.
std::vector<double> scores;
std::vector<double>::iterator pv = scroes.begin();
auto pv = scores.begin(); //요약 가능
'서적 정리 > C++ 기초 플러스' 카테고리의 다른 글
15.구조체(struct) (0) | 2022.08.03 |
---|---|
14.string 클래스 (0) | 2022.07.29 |
13.문자열(string) (0) | 2022.07.26 |
12.배열(array) (0) | 2022.07.26 |
10.부동 소수점수(floating point) (0) | 2022.07.25 |
9.const 제한자 (0) | 2022.07.25 |
8.간단한 변수 (0) | 2022.07.22 |
7.함수(function) (0) | 2022.07.20 |
댓글