
연산자(operator)는 자료에 대한 여러가지 연산을 수행하도록 하는 기호를 뜻한다.
2개의 자료를 대상으로 산술적인 계산을 수행하는 연산자이다.
| 연산자 | 기능 | 사용 예시 |
|---|---|---|
| + , - , * , / | 덧셈, 뺄셈, 곱셈, 나눗셈 계산 | a + 5 |
| % | 나눗셈의 나머지 계산 | a % 5 |
% 연산자는 나머지 연산자(modulo operator)라고도 하며, 실수형 자료에서 사용 불가하고 정수형에서만 가능하다.
⌨️ 예제 1
// 이항 연산자의 사용 예시
#include <stdio.h>
int main() {
int a = 7;
int b = 3;
printf("%d + %d = %d\n", a, b, a + b);
printf("%d - %d = %d\n", a, b, a - b);
printf("%d * %d = %d\n", a, b, a * b);
printf("%d / %d = %d\n", a, b, a / b); // "정수 ÷ 정수"는 정수 반환(몫 계산 가능)
printf("%d %% %d = %d\n", a, b, a % b); // "7 ÷ 3"의 나머지 값 계산
printf("%d %% %d = %d\n", b, a, b % a); // "3 ÷ 7"의 나머지 값 계산
}
🖥️ 실행 결과
7 + 3 = 10
7 - 3 = 4
7 * 3 = 21
7 / 3 = 2
7 % 3 = 1
3 % 7 = 3
이항 연산자와 다르게 1개의 자료만을 대상으로 한다. 단항 연산자 중 ++과 --를 증감 연산자라고도 한다.
| 단항 연산자 | 기능 | 사용 예시 |
|---|---|---|
| - | 부호의 반전 | -5 |
| ++ | 1 증가 | a++, ++a |
| -- | 1 감소 | a--, --a |
단항연산을 이항연산으로 변경할 수 있다.
증감 연산자는 정수형 변수에만 사용되어야 하며, 사용 위치에 따라 전치연산, 후치연산으로 나뉜다.
⌨️ 예제 2
// 전치 증가 연산
#include <stdio.h>
int main() {
int a = 10, b;
b = ++a; // 먼저 a에 1을 증가시칸 후, 그 값을 b에 대입
printf("a : %d\n", a);
printf("b : %d\n", b);
}
🖥️ 실행 결과
a : 11
b : 11
⌨️ 예제 3
// 후치 증가 연산
#include <stdio.h>
int main() {
int a = 10, b;
b = a++; // 먼저 b에 a 값을 저장한 후, a에 1을 더하기
printf("a : %d\n", a);
printf("b : %d\n", b);
}
🖥️ 실행 결과
a : 11
b : 10
위의 후치 증가 연산 예제에서 b = a++; 대신
b = a; // b에 a 값을 저장
a++; // a에 1을 더하기
으로 나누어서 작성하면 후치연산을 헷갈리지 않고 직관적으로 볼 수 있다.
대입 연산자는 '='을 사용하여 연산자의 오른쪽을 왼쪽에 대입한다. 수식을 압축하여 간단하게 기술할 수 있다.
| 연산자 | 기능 | 사용 예시 |
|---|---|---|
| = | a에 숫자 n을 대입 | a = n |
| += | a = a + n : a에 n을 더한 후 결과를 a에 대입 | a += n |
| -= | a = a - n : a에 n을 뺀 후 결과를 a에 대입 | a -= n |
| *= | a = a * n : a에 n을 곱한 후 결과를 a에 대입 | a *= n |
| /= | a = a / n : a에 n을 나눈 후 결과를 a에 대입 | a /= n |
| %= | a = a % n : a에 n을 나눈 후 그 나머지를 a에 대입 | a %= n |
| &= | a = a & n : a와 n에 대해 bit단위의 AND 연산을 한 후 결과를 a에 대입 | a &= n |
| |= | a = a | n : a와 n에 대해 bit단위의 OR 연산을 한 후 결과를 a에 대입 | a |= n |
| ^= | a = a ^ n : a와 n에 대해 bit단위의 XOR 연산을 한 후 결과를 a에 대입 | a ^= n |
관계 연산자는 피연산자에 대한 대소 관계를 비교하므로 비교 연산자라고도 하며, 수식의 결과가 참이면 1, 거짓이면 0을 돌려준다.
| 연산자 | 기능 | 사용 예시 |
|---|---|---|
| == | 같은가의 여부를 비교 | a == b : a와 b는 같다 |
| != | 다른가의 여부를 비교 | a != b : a와 b는 같지 않다 |
| >, >=, <=, < | 대소 관계를 비교 | a >= b : a는 b보다 크거나 같다 |
⌨️ 예제 4
#include <stdio.h>
#include <stdbool.h> // 부울 자료형을 사용하기 위한 헤더 파일
int main() {
int a = 2;
int b = 5;
bool p = a > b; // 2 > 5 는 거짓이므로 p = 0
bool q = a <= b; // a <= b 는 참이므로 q = 1
bool r = a == b; // a == b 는 거짓이므로 r = 0
printf("%d\n", p);
printf("%d\n", q);
printf("%d\n", r);
}
🖥️ 실행 결과
0
1
0
피연산자에 대해 논리연산을 수행하여 결과를 참과 거짓으로 나타내는 연산자다. 논리연산에서 값이 0일 경우에만 거짓이고, 0이 아닌 값은 참이 된다.
| 연산자 | 기능 | 사용 예시 |
|---|---|---|
| && | 논리곱(AND) : 양쪽 모두 참일 때만 참 | a && b |
| || | 논리합(OR) : 양쪽 중 하나라도 참이면 참 | a || b |
| ! | 논리부정(NOT) : 오른쪽이 참이면 거짓, 거짓이면 참 | !a |
⌨️ 예제 5
#include <stdio.h>
#include <stdbool.h>
int main() {
int a;
scanf("%d", &a);
bool p = a >= 1 && a <= 10; // 1 ≤ a ≤ 10 과 같은 의미
bool q = a == 3 || a == 7; // 두 조건 중 하나만 참이어도 참
bool r = !a; // a가 참이면 r은 거짓, a가 거짓이면 r은 참
printf("%d\n", p);
printf("%d\n", q);
printf("%d\n", r);
}
🖥️ 실행 결과
3 [Enter↵]
1
1
0
?와 :를 사용하여 (조건) ? 수식1 : 수식2 의 형식으로 작성한다. 주어진 조건이 참이면 수식1을, 거짓이면 수식2를 수행하는 기능을 갖고 있으며, if문의 기능이 내장된 3항 연산자라고 볼 수 있다.
⌨️ 예제 6
#include <stdio.h>
int main() {
int a = 3, b, c;
b = (a > 0) ? (a + 3) : (a + 6); // 조건을 만족하므로 a + 3 수행
c = (a > 10) ? (a + 3) : (a + 6); // 조건을 불만족하므로 a + 6 수행
printf("b = %d\n", b);
printf("c = %d\n", c);
}
🖥️ 실행 결과
b = 6
c = 9
비트 연산자는 수치를 2진수로 변환하여 비트(bit) 단위로 하나씩 연산을 수행한다. 정수형 자료에서만 사용 가능한 연산자다.
&, |, ~는 각각 논리 연산자의 &&, ||, !와 모양이 비슷하다.
| 연산자 | 기능 | 사용 예 |
|---|---|---|
| & (bit AND) | 대응되는 두 비트가 모두 1일때만 1 반환 | a & b |
| | (bit OR) | 대응되는 두 비트 중 하나라도 1이면 1 반환 | a | b |
| ^ (bit XOR) | 대응되는 두 비트가 서로 다를 때만 1 반환 | a ^ b |
| ~ (bit NOT) | 1은 0으로, 0은 1로 반환 | ~a |
⌨️ 예제 7
#include <stdio.h>
int main() {
char a = 15, b = 10;
printf("%d\n", a & b);
printf("%d\n", a | b);
printf("%d\n", a ^ b);
printf("%d\n", ~a);
}
🖥️ 실행 결과
10
15
5
-16
&, |, ^는 2개의 비트값을 맨 앞자리부터 한 비트씩 서로 비교한다. 또한 맨 앞의 비트는 부호를 표시하기 위해 사용하기 때문에, 이 비트가 1일 경우 음수값이 반환된다. ~a의 경우 2의 보수를 사용해서 -16이 출력됐다.
< 변수 a와 b 비트연산 예>
| ~a : | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | -16 |
|---|---|---|---|---|---|---|---|---|---|
| a : | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 15 |
| b : | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 10 |
| a&b : | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 10 |
비트를 이동시키는 연산자다. 모든 비트들이 왼쪽 또는 오른쪽으로 n비트씩 이동하며, 맨 왼쪽 또는 오른쪽에 있다가 밀려난 비트들은 버려지고, 밀어내고 난 뒤 비어진 자리는 0으로 채운다.
| 연산자 | 기능 | 사용 예 |
|---|---|---|
| << | a 값에 대해 n비트 왼쪽으로 이동 | a << n |
| >> | a 값에 대해 n비트 오른쪽으로 이동 | a >> n |
⌨️ 예제 8
#include <stdio.h>
int main() {
char a = 30; // 00011110(2) → 8bit로 십진수 30 표현
// 왼쪽으로 이동
printf("%d\n", a << 1); // 00111100(2) == 60(10) → 000111100(2)
printf("%d\n", a << 3); // 11110000(2) == 240(10) → 00011110000(2)
printf("%d\n", a << 6); // 10000000(2) == 128(10) → 00011110000000(2)
// 오른쪽으로 이동
printf("%d\n", a >> 1); // 00001111(2) → 오른쪽으로 이동한 비트는 무조건 잘리게 됨
printf("%d\n", a >> 3); // 00000011(2)
printf("%d\n", a >> 6); // 00000000(2)
}
🖥️ 실행 결과
60
240
1920
15
3
0
a를 왼쪽으로 3, 6만큼 이동해서 나온 십진수 240, 128은 char형 범위에서 벗어난다. 이럴 경우에는 char형 대신 자동으로 범위에 맞는 int형 등으로 바꿔서 계산된다. 그러면 수용 가능한 비트 수가 더 많아지므로 8bit가 넘어간 비트까지 포함해서 계산할 수 있게 된다. "a << 3"의 경우 잘렸던 비트가 전부 0이어서 앞부분에 포함시켜도 계산값이 달라지지 않지만, "a << 6"은 11110000000이 되어 1920이라는 숫자가 나온다.
괄호 안에 지정한 자료형, 수식, 변수가 차지하는 기억공간의 크기(byte)를 구하는 연산자다.
⌨️ 예제 9
#include <stdio.h>
int main() {
// 괄호 안에 자료형을 넣는 경우
printf("%lu%lu%lu%lu\n", sizeof(int), sizeof(char), sizeof(float), sizeof(double));
// 괄호 안에 변수를 넣는 경우
int a; char b; float c; double d;
printf("%lu%lu%lu%lu\n", sizeof(a), sizeof(b), sizeof(c), sizeof(d));
}
🖥️ 실행 결과
4148
4148
sizeof 함수는 unsigned long형으로 출력되기 때문에 %lu를 사용한다.
cast 연산자를 사용해 임의의 자료에 이미 지정된 자료형을 다른 자료형으로 강제 변환할 수 있다.
'(변환할 자료형)자료' 의 형식으로 사용한다.
⌨️ 예제 10
// 수학, 국어, 영어 3과목 점수의 평균 구하기
#include <stdio.h>
int main() {
int math = 90, korean = 95, english = 96;
int sum = math + korean + english;
double avg = sum / 3;
printf("%f\n", avg);
}
🖥️ 실행 결과
93.000000
잘못된 값이 출력되는 이유는 sum / 3; 이 "정수 ÷ 정수"이어서 변수 avg 값도 자동으로 정수가 됐기 때문이다.
→ 정수보다 실수가 더 크기 때문에(더 많은 값 저장 가능) 연산의 결과값은 더 큰 쪽의 자료형이 된다.
이처럼 여러 자료형의 값들이 한 수식에 같이 포함되어 있을 경우, 자동적으로 형 변환이 일어나는 것을 묵시적 형 변환(implicit type conversion)이라고 한다.
🛠️ 코드 수정
#include <stdio.h>
int main() {
int math = 90, korean = 95, english = 96;
int sum = math + korean + english;
double avg = (double)sum / 3; // sum이 해당 라인 코드가 실행되는 동안만 실수형 변수로 바뀜
printf("%f\n", avg);
}
🖥️ 실행 결과
93.666667
변수 sum의 자료형을 double로 변경해도 되지만, 정수값만 저장되는 sum에 실수를 저장할 필요가 없으므로 형변환 연산자를 사용하여 강제로 자료형을 일치시켰다.
& : 주소 연산자로서 피연산자의 주소를 나타냄
* : 내용 연산자로서 피연산자의 내용을 가져옴(특정 주소의 기억공간 안의 내용)
참조 : [C] 포인터