산술 연산자란, 흔히 우리가 계산할 때 사용하는 사칙연산을 의미합니다.
C언어에서 산술 연산자의 종류에는 덧셈(+), 뺄셈(-), 곱셈(*), 나눗셈(/) 외에 나머지연산(%)이라는 것이 존재합니다. 연산자의 사용에 있어서 기억해야 할 것은 정수형 데이터 간의 연산 결과는 정수가 되며, 실수형 데이터간의 연산 결과는 실수가 된다는 것입니다.
|
연산자 |
사용법 |
의 미 |
|
+ |
a+b |
a에 저장된 값과 b에 저장된 값을 더한다 |
|
- |
a-b |
a에 저장된 값에서 b에 저장된 값을 뺀다 |
|
-a |
a에 저장된 값의 부호를 바꾼다 | |
|
* |
a*b |
a에 저장된 값과 b에 저장된 값을 곱한다 |
|
/ |
a/b |
a에 저장된 값을 b에 저장된 값으로 나눈다 |
|
% |
a%b |
a에 저장된 값을 b에 저장된 값으로 나눈 나머지 |
printf("%d\n", 12/4);
printf("%d\n", 12%4);
첫번째 printf()문은 3을 출력하며, 두번째 printf()문은 0을 출력합니다.
즉, 나눗셈연산은 몫을 값으로 가지며, 나머지연산은 그 나머지를 값으로 가지는 연산입니다.
* 증가, 감소 연산자 (++, --)
C언어에는 산술 연산자 외에 증가, 감소 연산자라는 것이 있습니다. 대부분의 연산자들은 a+b 또는 a%b와 같이 두 개의 피연산자를 필요로하는 이항(Binary) 연산자이지만 특이하게 이 연산자들은 피연산자가 하나만 있는 경우에도 사용할 수 있는 단항(unary) 연산자 입니다. 증가, 감소 연산자는 오직 변수의 앞 또는 뒤에서 사용되어 저장된 값을 1증가시키너나 감소시키므로 상수나 식에 사용할 수 없습니다.
|
++ 연산자 |
-- 연산자 | ||
|
연산식 |
의 미 |
연산식 |
의 미 |
|
a++; |
a=a+1; |
b++; |
b=b+1; |
|
++a; |
++b; | ||
증가연산자 ++와 감소 연산자 -- 가 변수 앞에 위치하는 경우를 선행(prefix) 연산이라 하며 변수 뒤에 사용되는 경우를 후행(postfix) 연산이라 합니다. 의미 상으론 1을 증가시키거나 감소시키는 것이지만, 프로그램내에서 선행연산과 후행연산은 차이가 있습니다. 다음 프로그램을 봅시다.
#include <stdio.h>
void main() <실행 결과>
{
int a=10, b=20; a=10
a=12
printf("a=%d\n", a++); b=20
printf("a=%d\n", ++a); b=18
printf("b=%d\n", b--);
printf("b=%d\n", --b);
}
선행 연산에서는 변수의 값을 먼저 증가시키거나 감소시킨 다음 변수를 평가하며, 후행 연산에서는 변수에 대한 평가를 먼저 처리한 후에 변수의 값을 증기시키거나 감소시킵니다. 첫 번째 printf()문에서 a++은 후행 연산이므로 a의 값 10을 먼저 출력 후에 증가되어 11이 되고, 두 번째 printf()문에서는 선행 연산 이므로 11이 된 a의 값을 1증가 시킨 뒤 12를 출력하는 것입니다. 이와 마찬가지로 b역시 b-- 는 후행 연산이므로 20을 출력하고 1감소되어 19가 되고 --b 는 선행 연산이므로 19를 다시 1감소하여 18을 출력하는 것입니다.
* 대입 연산자 (=, +=, *=, ...)
변수에 어떤 값을 저장할 때에는 대입(assignment) 연산자 = 를 이용합니다. 수학에선 등호로서 = 를 중심으로 좌변과 우변이 같다는 의미이지만, 대부분의 프로그램 언어에서 대입 연산자는 우측의 연산 결과값을 좌측의 변수에 대입한다는 의미입니다. 따라서, a=b 라는 것은 수학에선 'a와 b는 같다' 이지만 프로그램에선 '변수 a에 b를 대입한다' 라는 의미가 되는 것입니다.
|
대입 연산자 |
사용 예 |
연산과 의미 |
|
= |
a=b=0; |
a=0; and b=0; |
|
+= |
a+=b; |
a=a+b; |
|
-= |
a-=b; |
a=a-b; |
|
*= |
a*=b; |
a=a*b; |
|
/= |
a/=b; |
a=a/b; |
|
%= |
a%=b; |
a=a%b; |
* 연산 순서
연산은 기본적으로 식의 좌측에서 우측 방향으로 이동하면서 이루어지는데 식에 사용된 연산자에 따라서 연산의 순서가 달라집니다.
[연산식의 처리 순서에 대한 기본 원칙]
① 연산식의 좌측에서 우측으로 이동하며 연산한다
② 단, 괄호가 사용된 경우에는 괄호 부분을 먼저 연산한다
③ 곱셈이나 나눗셈 연산자는 덧셈이나 뺄셈 연산자보다 우선적이다.
다음은 산술 연산자의 우선순위(precedence) 입니다.
|
순 위 |
연산자 |
연산자 |
|
높음 ↓ 낮음 |
괄호 |
( ) |
|
증가, 감소 |
++, -- | |
|
사칙연산 |
*, /, % | |
|
+, - |
* 관계 연산자 (<, >, ==, !=, ...)
관계 연산자(Relational operator)는 데이터 간의 대소 관계를 비교하는데 사용하며 산술 연산과 마찬가지로 관계 연산의 경우에도 연산 결과를 값으로 가집니다. 하지만, 관계 연산의 경우엔 수식계산이 아니기때문에 True(1), Flase(0) 만을 결과 값으로 가지게 됩니다.
|
연산자 |
사용법 |
의 미 |
결과값 |
|
< |
a<b |
a에 저장된 값이 b에 저장된 값보다 작은가? |
참(True) : 1,
거짓(False) : 0 |
|
<= |
a<=b |
a에 저장된 값이 b에 저장된 값보다 작거나 같은가? | |
|
> |
a>b |
a에 저장된 값이 b에 저장된 값보다 큰가? | |
|
>= |
a>=b |
a에 저장된 값이 b에 저장된 값보다 크거나 같은가? | |
|
== |
a==b |
a에 저장된 값과 b에 저장된 값이 같은가? | |
|
!= |
a!=b |
a에 저장된 값과 b에 저장된 값이 다른가? |
관계 연산나 중에서 동등관계를 비교하는 연산자는 == 이므로 대입 연산자 = 와 구분해서 써야합니다.
* 조건 연산자 (? :)
조건 연산자(Conditional operator)는 3개의 피연산자를 사용하는 3항 연산자로서 ?와 : 조합으로 표현합니다.
|
연산자 |
사용법 |
의 미 |
|
? : |
수식 1 ? 수식 2 : 수식 3 |
수식1의 연산 결과가 참(1)이면 수식2를 처리 수식1의 연산 결과가 거짓(0)이면 수식3을 처리 |
|
k = (a>b) ? a : b; |
a가 b보다 크면 k에 a값을 저장 그렇지 않는 경우는 k에 b값을 저장 |
* 논리 연산자 (&&, ||, !)
논리 연산자(Logical operator)는 두 가지 이상의 조건에 대한 논리적인 판단에 사용하며 관계 연산과 마찬가지로 논리 연산의 경우에도 연산 결과에 따라 참이면 1을 거짓이면 0을 결과값으로 가집니다.
|
연산자 |
사용법 |
의 미 |
|
&& |
a && b |
a에 저장된 값과 b에 저장된 값의 논리곱 (AND) |
|
|| |
a || b |
a에 저장된 값과 b에 저장된 값의 논리합 (OR) |
|
! |
!a |
a에 저장된 값에 대한 부정 (NOT) |
위에 보면 논리곱과 논리합, 부정이 나오는데요. 논리곱(AND)이란, a와 b값 둘다 참이면 결과값은 참(Ture)이되고 논리합(OR)이란, a나 b 둘 중 하나만 참이면 결과는 참(Ture)이 됩니다. 부정(NOT)은 값이 참이면 거짓으로, 거짓이면 참으로 바꾸는 것입니다. 다음은 논리 연산에 대한 진리표입니다.
|
a |
b |
a && b |
a || b |
!a |
|
0 |
0 |
0 |
0 |
1 |
|
0 |
1 |
0 |
1 |
1 |
|
1 |
0 |
0 |
1 |
0 |
|
1 |
1 |
1 |
1 |
0 |
* 비트 연산자 (<<, >>, ^, ...)
모든 데이트들은 컴퓨터 안에서 bit로 표현되고 저장됩니다. 비트 연산자(Bit operator)는 비트로 표현되거나 저장된 데이터들에 대해서 비트 단위의 연산을 처리합니다.
|
구분 |
연산자 |
사용법 |
의 미 |
|
비트 논리 연산자 |
~ |
~a |
a에 저장된 값에 대한 1의 보수 |
|
& |
a & b |
a에 저장된 값과 b에 저장된 값의 비트단위의 논리곱 | |
|
| |
a | b |
a에 저장된 값과 b에 저장된 값의 비트단위의 논리합 | |
|
비트 시프트(Shift) 연산자 |
^ |
a^b |
a에 저장된 값과 b에 저장된 값의 비트단위의 배타적 논리곱 |
|
<< |
a<<n |
a에 저장된 값에 대해 n비트 만큼 왼쪽으로 시프트 | |
|
>> |
a>>n |
a에 저장된 값에 대해 n비트 만큼 오른쪽으로 시프트 |
시프트(Shift)라는 의미는 "자리를 옮기다, 이동하다" 라는 뜻으로 비트 시프트 연산은 피연산자의 비트열에 대해 왼쪽 또는 오른쪽으로 자리 이동 연산을 처리합니다. 비트 시프트 연산자는 2항 연산자로서 이동 위치를 나타내는 연산자 >> 또는 << 와 이동시킬 자리수를 나타내는 상수 또는 변수를 필요로 합니다. 시프트 연산자는 정수형 데이터에만 사용할 수 있으며, 비트열의 자리 이동에 의해 원래 데이트의 부호가 바뀔 수 있으므로 부호 없는(Unsigned) 정수형 데이터를 사용합니다. 비트 연산을 하는 과정은 변수 또는 상수를 8비트 2진수로 변환 시킨 후 오른쪽 시프트는 오른쪽으로 1칸씩 이동, 왼쪽 시프트는 왼쪽으로 1칸씩 이동시킨 후 다시 10진수로 변환하면 됩니다. 예를 들어 보겠습니다.
8 << 2 : 10진수 8을 왼쪽으로 2칸 옮기라는 뜻입니다. 우선 8을 8비트 2진수로 변환 시킵니다.
10진수 8은 2진수 00001000 입니다. 자, 이제 << 연산을 수행하기 위해 왼쪽으로 2칸 이동시킵니다.
그러면 값이 00100000 이 됩니다. 1의 위치를 잘보면 2칸 왼쪽으로 이동한 게 보이죠? 이제 시프트 연산을 한 2진수를 다시 10진수로 바꾸면 결과는 32가 됩니다. 오른쪽 시프트도 이와 같이 하면 됩니다.
* 형 변환과 캐스트(Cast) 연산자
변수를 사용하기 전에, 변수 선언 부분에서 데이터 형을 결정해야 합니다. 정수형으로 변수를 선언하고 실수형 값을 입력하면 소수이하 부분은 제외되고 정수부분만 저장됩니다. 반대로 실수형 변수에 정수형 값을 저장하면 손실이 없이 저장은 되지만 형 변환(Type conversion)이 일어납니다. 어린이는 어른들의 신발을 신을 수 있어도 어른들은 어린이들의 신발을 못신는거랑 비슷한 원리입니다. 이러한 형 변환은 연산에서도 일어납니다. 연산식에 적어도 한 개의 실수형 데이터가 포함될 경우나 정수형 변수 두 개를 나눗셈 연산을 했을 경우, 나누어 떨어지지 않는다면 결과가 실수형이 될 것입니다. 보통은 컴파일러에 의해 자동적으로 처리되는데 이를 암시적(Implicit) 형 변환이라고 합니다. 또 프로그래머가 강제로 형 변환을 할 수 있는데요, 이를 명시적(Explicit) 형 변환이라하며 캐스트(Cast) 연산자를 사용합니다.
|
캐스트 연산자 사용법 |
의 미 |
|
(float) a / 3.14 |
변수 a를 float형으로 변환하여 연산 |
|
(int) (a / b) |
a/b의 연산 결과를 int 형으로 변환 |
* sizeof 연산자
sizeof 연산자는 상수, 변수 그리고 연산식 결과의 크기를 Byte로 표시해 주는 연산자로서 대부분의 연산자가 기호로 사용되는 것에 비해 연산자의 이름을 그래도 사용합니다.
사용법은 sizeof(변수명, 상수명 또는 연산식) 입니다.
* 연산자 우선순위
결합방향이란 연산의 진행 방향을 의미합니다. 이항 연산자들은 좌측에서 우측방향으로, 대입 연산자는 오른쪽의 연산 결과를 왼쪽의 변수에 저장하므로 결합방향은 반대가 됩니다.
아래의 표는 C 언어에서 사용하는 모든 연산자에 대한 우선순위와 식의 결합방향입니다.
|
순위 |
연산자 구분 |
연산자 |
결합방향 | |
|
높음
↓ |
일차식 |
(), [], ->, .(dot) |
→ | |
|
단항 |
++, --, sizeof, ~, ! |
← | ||
|
+, -, &, *, cast연산자 | ||||
|
승제 |
*, /, % |
→ | ||
|
가감 |
+, - |
→ | ||
|
시프트 |
<<, >> |
→ | ||
|
비교 |
<, <=, >=, > |
→ | ||
|
등가 |
==, != |
→ | ||
|
비트 |
&, ^, | |
→ | ||
|
논리 |
&&, || |
→ | ||
|
조건 (3항) |
? : |
← | ||
|
대입 |
=, +=, -=, *=, /=, %=, <<=, >>=, &-, ^=, |= |
← | ||
|
콤마 |
, |
→ | ||
♪ 직접 공부하여 정리한 소중한 자료이므로 담아 가실 땐 꼭 출처를 밝혀주세요.

