앞서 정수와 실수의 메모리 표현 방식을 알아보았다. 이번 글에서는 데이터를 계산할 때 사용하는 가장 기본적인 산술 연산자, 연산 시 발생하는 임시 메모리 저장, 그리고 나누기(/)와 나머지(%) 연산자의 특수성을 정리한다.
1. 기본 산술 연산자와 대입 연산자
C/C++에서 식을 구성할 때 사용하는 연산자는 우측의 피연산자를 기반으로 연산을 수행한다.
-
덧셈(
+), 뺄셈(-), 곱셈(*): 일반적인 사칙연산과 동일하게 동작한다. -
대입 연산자(
=harness): 우항의 값을 좌항의 변수에 저장(메모리 이동)한다.
int data = 10;
data = data + 20; // 10 + 20의 결과를 data 변수에 다시 대입
2. 연산자 우선순위와 연산 과정의 임시 저장
컴퓨터는 지시된 명령어에 따라 엄격한 우선순위를 적용하여 계산한다.
int a = 10 + 5 * 2; // 곱셈(*)이 덧셈(+)보다 우선순위가 높아 10 + 10 = 20이 됨
연산 결과는 어디에 담기는가?
CPU가 연산을 수행할 때, 연산 과정의 중간 결과는 CPU 내부의 레지스터(Register) 등 임시 메모리 공간에 잠시 머무른다.
만약 data + 20;처럼 연산만 하고 대입 연산자(=)를 사용하지 않으면, 연산 결과는 변수에 반영되지 않고 그대로 휘발되어 사라진다.
3. 복합 대입 연산자
자기 자신의 값에 특정 연산을 수행한 후 다시 자신에게 저장하는 구문은 복합 대입 연산자를 사용해 간결하게 축약할 수 있다.
int data = 10;
data = data + 20; // 일반적인 대입 구문
data += 20; // 복합 대입 연산자 (동일하게 동작)
data *= 2; // data = data * 2 와 동일
4. 나누기(/)와 나머지(%) 연산자의 특수성
나누기 연산은 피연산자의 자료형(정수 vs 실수)에 따라 동작 방식이 완전히 달라진다.
1) 정수 나눗셈과 나머지 연산자
-
정수 나눗셈(
/): 소수점을 표기할 수 없으므로, 몫만 남고 소수점 아래는 버려진다. -
나머지 연산자(
%, 모듈러스): 나눗셈 후 남은 나머지를 구한다. 오직 정수형 피연산자끼리만 사용 가능하다.
int quotient = 10 / 3; // 결과: 3 (소수점 이하 버림)
int remainder = 10 % 3; // 결과: 1 (나머지)
2) 실수 나눗셈의 주의점
실수 나눗셈에서는 소수점 이하까지 연산이 수행되므로 나머지라는 개념 자체가 존재하지 않는다. 따라서 실수에 % 연산자를 사용하면 컴파일 에러가 발생한다.
double a = 10.0 / 3.0; // 결과: 3.333333...
// double b = 10.0 % 3.0; // ❌ 문법 오류 (실수에는 % 사용 불가)
5. 상수 리터럴의 자료형과 명시적 형변환
코드에 직접 작성하는 숫자를 상수(Literal)라고 부른다. 코드에 적힌 상수는 그 자체로 특정 자료형과 크기를 갖는다.
int i = 10; // 10은 4바이트 정수(int)
double d = 3.14; // 소수점만 적으면 8바이트 실수(double)
float f = 3.14f; // 숫자 뒤에 'f'를 붙이면 4바이트 실수(float)
데이터 손실과 컴파일러 경고
실수 연산 결과(예: 3.333)를 정수형(int) 변수에 대입하려 하면 소수점이 잘려 나가며 데이터 손실 경고(Warning)가 발생한다. 이 경우 명시적 형변환을 통해 컴파일러에게 의도를 전달해야 한다.
int result = (int)(10.0 / 3.0); // (int)로 명시적 형변환 -> 경고 제거
마무리하며
-
연산만 수행하고 변수에 대입하지 않으면 중간 결과는 휘발된다.
-
%(나머지) 연산자는 정수끼리만 가능하며 실수에는 사용할 수 없다. -
코드에 직접 적는 실수 상수는 기본적으로
double타입이므로,float변수에 담을 때는f접미사를 붙여주도록 하자.