프로그램은 CPU가 처리하는 명령어의 묶음입니다. 일반적으로 연산자는 컴파일되면 명령어로 바뀌므로 연산자를 배우는 것은 결국 명령어를 익히는 겁니다. 연산 명령에는 연산의 대상이 되는 데이터가 필요한데 이를 피연산자라고 합니다. 피연산자는 숫자, 변수 그리고 수식이 될 수 있습니다.
산술 연산자와 대입 연산자
산술 연산자
산술 연산자에는 더하기(+), 빼기(-), 곱하기(*), 나누기(/), 나머지(%)가 있습니다. 모두 2개의 피연산자를 사용하며 이 중 빼기(-) 연산자는 피연산자를 하나만 사용할 때 피연산자의 부호를 바꾸는 역할도 합니다.
#include <stdio.h>
int main(void){
int a,b;
int sum, sub, mul, rest, inv;
a = 10;
b = 20;
sum = a + b; // 더하기
sub = a - b; // 빼기
mul = a * b; // 곱하기
rest = a % b; // 나머지
inv = -a; // 부호 바꾸기
printf("a의 값 : %d, b의 값 : %d\n", a, b);
printf("sum의 결과 : %d\n", sum); // 더하기 결과
printf("sub의 결과 : %d\n", sub); // 빼기 결과
printf("mul의 결과 : %d\n", mul); // 곱하기 결과
printf("rest의 결과 : %d\n", rest); // 나누기 결과
printf("inv의 결과 : %d\n", inv); // 부호 바꾸기 결과
printf("\n");
// 나누기
printf("5.0 / 2.0 = %.1lf\n", 5.0/2.0);
printf("5.0 / 2 = %.1lf\n", 5.0/2);
printf("5 / 2.0 = %.1lf\n", 5/2.0);
printf("5 / 2 = %d\n", 5/2);
return 0;
}
실행 결과
a의 값 : 10, b의 값 20
sum의 결과 : 30
sub의 결과 : -10
mul의 결과 : 200
rest의 결과 : 10
inv의 결과 : -10
5.0 / 2.0 = 2.5
5.0 / 2 = 2.5
5 / 2.0 = 2.5
5 / 2 = 2
대입 연산자
변수에서 많이 다뤄봤죠? =을 대입 연산자라고 합니다. 오른쪽 수식의 결과(r-value)를 왼쪽 변수(l-value)에 저장합니다. 수식은 수식과 상수, 변수 모두 포함합니다.
위 코드에서 a = 10; b = 20; sum = a + b; .... 등등이 대입 연산자를 사용한 것입니다.
증감 연산자
a라는 int형 변수에 1을 더하려면 a = a + 1; 이라고 쓰면 됩니다. 하지만 더 간단히 ++a;로 표현할 수도 있습니다. --a;처럼 빼기도 가능합니다.
이러한 표현은 앞으로 배울 for문, while문, do while문 같은 반복문에서 자주 사용됩니다. 증감 연산자는 변수의 값을 1씩 증가시키거나 감소시킬 때 쉽게 사용할 수 있습니다.
#include <stdio.h>
int main(void){
int a = 10, b = 10;
++a;
--b;
printf("a : %d\n", a);
printf("b : %d\n", b);
return 0;
}
실행 결과
a : 11
b : 9
증감 연산자는 대입 연산을 포함하므로 (++a >> a = a + 1) 상수에는 사용할 수 없습니다. (ex. ++10)
전위 표기와 후위 표기
증감 연산자의 위치는 변수 앞 뿐만 아니라 뒤에도 올 수 있습니다.
전위 표기는 증감이 연산보다 먼저 일어나고 후위 표기는 증감이 연산을 하고 나서 증감합니다. 때에 따라 결과가 같을 수도, 다를 수도 있으니 필요한 방법을 사용하시면 됩니다.
#include <stdio.h>
int main(void){
int a = 5, b = 5;
int pre, post;
pre = (++a) * 3;
post = (b++) * 3;
printf("증감 연산 후 값 : a = %d, b = %d\n", a, b);
printf("전위형 : (++a) * 3 = %d, 후위형 : (b++) * 3 = %d\n", pre, post);
return 0;
}
실행 결과
증감 연산 후 값 : a = 6, b = 6
전위형 : (++a) * 3 = 18, 후위형 : (b++) * 3 = 15
전위형은 6*3의 결과가, 후위형은 5*3의 결과가 나왔습니다. 연산이 될 때는 a=6, b=5로 계산이 됐지만 연산 이후 a, b값을 보면 두 개 모두 6임을 확인하실 수 있습니다. 결국 전위 표기는 증감이 이루어진 뒤에 연산이, 후위 표기는 연산이 이루어진 뒤에 증감이 됨을 알 수 있습니다.
관계 연산자
프로그래밍을 하다보면 조건에 따라 명령을 실행해야 하는 경우도 있습니다. 이때 특정 기준, 조건에 관해 명령을 실행하려면 관계 연산자가 필요합니다.
관계 연산자에는 대소 관계 연산자와 동등 관계 연산자가 있습니다.
- 대소 관계 연산자 : >, <, >=, <=
- 동등 관계 연산자 : ==, !=
이들 모두 피연산자가 두 개가 필요하며 연산 결과는 1, 0 입니다. 컴파일러는 1과 0으로 참(true)과 거짓(false)을 판단하므로 관계식을 실행 조건 검사에 사용할 수 있습니다.
#include <stdio.h>
int main(void){
int a = 10, b = 20, c = 10;
int res;
res = (a > b);
printf("a > b : %d\n", res);
res = (a >= b);
printf("a >= b : %d\n", res);
res = (a < b);
printf("a < b : %d\n", res);
res = (a <= b);
printf("a <= b : %d\n", res);
res = (a <= c);
printf("a <= c : %d\n", res);
res = (a == b);
printf("a == b : %d\n", res);
res = (a != c);
printf("a != c : %d\n", res);
return 0;
}
실행 결과
a > b : 0
a >= b : 0
a < b : 1
a <= b : 1
a <= c : 1
a == b : 0
a != c : 0
이 예제에서는 계산만 하고 끝났지만 대부분의 프로그래밍에서는 주로 판단의 근거로 관계 연산의 결과를 사용합니다.
이때 == 사용 시 주의하셔야 합니다. =를 한 번만 쓰면 대입 연산자가 되어버리기 때문입니다. (a = 5 ≠ a == 5)
논리 연산자
논리 연산자는 논리 관계를 판단하는 데 사용하며 &&(AND), ||(OR), !(NOT) 3가지뿐입니다.
- && : 논리곱 연산자, 2개의 피연산자가 모두 참일 때만 연산 결과가 참이 된다.
- || : 논리합 연산자, 2개의 피연산자 중 하나라도 참이면 연산 결과가 참이 된다.
- ! : 논리부정 연산자, 하나의 피연산자의 결과(참 혹은 거짓)를 바꾼다.
#include <stdio.h>
int main(void){
int a = 10;
int res;
res = (a > 5) && (a < 10);
printf("(a > 5) && (a < 10) : %d\n", res);
res = (a < 5) || (a >= 10);
printf("(a < 5) || (a >= 10) : %d\n", res);
res = !(a >= 10);
printf("!(a >= 10) : %d\n", res);
return 0;
}
실행 결과
(a > 5) && (a < 10) : 0
(a < 5) || (a >= 10) : 1
!(a >= 10) : 0
수학에서는 5 < a < 10 처럼 한 번에 범위를 지정할 수 있지만, 프로그래밍에서는 따로따로 지정해 주고 &&(논리곱)으로 묶어줘야 합니다. (a > 5) && (a < 10)
숏 서킷 룰 (short circuit rule)
&&와 ||은 숏 서킷 룰이 적용됩니다. 숏 서킷 룰이란 좌항만으로 &&, ||의 결과를 판단하는 기능입니다. 예를 들어 &&는 좌항이 거짓이면 우항과 관계없이 결과가 거짓이므로 우항을 살펴볼 필요가 없습니다. 또한 ||는 좌항이 참이면 우항의 결과와 상관없이 참이므로 우항을 살펴볼 필요가 없습니다.
숏 서킷 룰을 사용하실 때에는 주의하셔야 합니다. 잘못하면 중요한 논리 에러를 일으킬 수 있습니다. 예를 들어 항상 ++b가 실행되길 바라고 (a > 10) && (++b > 20) 처럼 코딩을 하면 원하는 결과를 얻으실 수 없을 것입니다. a가 10보다 크면 b는 증가하지 않을 테니 말이죠.