본문 바로가기

개발/C

[C언어]기초 - 04. 연산자

※해당 포스팅은 "혼자 공부하는 C언어"책을 기반으로 작성되었습니다.

 

산술 연산자와 대입 연산자

01. 산술 연산자

 : 수학에서도 많이 사용하는 더하기, 빼기 등의 연산을 의미

º 종류 : 더하기(+), 빼기(-), 나누기(/), 나머지(%)

º 2개의 피연산자를 사용

 

02. 대입 연산자

 : = 는 대입연산자라 하며 오른쪽 수식의 결과를 왼쪽 변수에 저장

 

º 대입, 덧셈, 뺄셈, 곱셉, 음수 연산 예제 코드

#include <stdio.h>
int main(void)
{
	int a, b;
	int sum, sub, mul, inv;

	a = 5;
	b = 10;
	sum = a + b;
	sub = a - b;
	mul = a * b;
	inv = -a;

	printf("a의 값 : %d, b의 값 : %d\n", a, b);
	printf("덧셈 : %d\n", sum);
	printf("곱셈 : %d\n", sub);
	printf("뺄셈 : %d\n", mul);
	printf("a의 음수 연산 : %d\n", inv);

	return 0;
}

º 실행 결과

a의 값 : 5, b의 값 : 10
덧셈 : 15
뺄셈 : -5
곱셈 : 50
a의 음수 연산 : -5

 

 

03. 나누기 연산자와 나머지 연산자

º 나누기 연산자 : / 연산자 사용

 - 정수 연산 시 : 몫을 구함

 - 실수 연산 시 : 소수점까지 구함

º 나머지 연산자 : % 연산자 사용

 - 몫을 뺀 나머 값을 구할 때 사용

 - 실수 연산에는 나머지의 개념이 없으므로 피연산자는 정수만 사용

 

º 몫과 나머지를 구하는 연산자 예제 코드

#include <stdio.h>
int main(void)
{
	double a;
	int b, c;

	a = 5.0 / 2.0;
	b = 5 / 2;
	c = 5 % 2;

	printf("a : %.1lf\n", a);
	printf("b : %d\n", b);
	printf("c : %d\n", c);

	return 0;
}

º 실행 결과

a : 2.5
b : 2
c : 1

 

03. 증감 연산자

º ++a : 증가 연산자 / --a : 감소 연산자

º for문, while문, do while문과 같은 반복문에서 루프마다 하나씩 더하거나 뺄 때 자주 사용

º 하나의 연산자로 대입 연산까지 수행

º 증감 연산자의 연산 예제 코드

#include <stdio.h>
int main(void)
{
	int a = 1, b = 10;

	++a;
	--b;
	printf("a : %d\n", a);
	printf("b : %d\n", b);
	return 0;
}

º 실행 결과

a : 2
b : 9

º 전위 표기와 후위 표기

 - 전위 표기 : 증감 연산자가 피연산자 앞에 위치

    → 다른 연산자와 함께 사용 시, 증감 연산자 먼저 실행 후 다른 연산자 실행

 - 후위 표기 : 증감 연산자가 피연산자 뒤에 위치

    → 다른 연산자와 함께 사용 시, 다른 연산자 먼저 실행 후 증감 연산자 실행

º 전위 표기와 후위 표기를 사용한 증감 연산 예제 코드

#include <stdio.h>
int main(void)
{
	int a = 10, b = 10;
	int pre, post;

	pre = (++a) * 3;
	post = (b++) * 3;

	printf("초깃값 a = %d, b = %d\n", a, b);
	printf("전위형 = %d, 후위형 = %d", pre, post);

	return 0;
}

º실행 결과

초깃값 a = 10, b = 10
전위형 = 33, 후위형 = 31

 

04. 관계 연산자

º 특정한 기준, 조건에 관해 명령할 때 사용

º 대소 관계 연산자 : < 또는 > 등의 기호를 사용

º 동등 관계 연산자 : == 또는 != 기호 사용

    → 모든 연산자는 두 개의 피연산자 필요

º 연산의 결과값은 1과 0으로 출력

 - 거짓(False) : 0

 - 참(True) : 0이 아닌 값, 1을 대표로 사용

º 주로 판단의 근거로 관계 연산의 결과를 활용

 

05. 논리 연산자

º 참과 거짓을 판단하는데 사용

º &&(AND), ||(OR), !(NOT) 세가지 연산자를 사용

º && : 논리곱 연산자, 두 개의 피연산자가 모두 참일 경우에만 연산 결과가 참

º || : 논리합 연산자, 둘 중 하나라도 참이라도 연산 결과가 참

º ! : 논리부정 연산자, 피연산자는 하나를 사용하여 참과 거짓을 바꿀 때 사용

º 논리 연산의 결괏값 예제 코드

#include <stdio.h>
int main(void)
{
	int a = 38;
	int res;

	//두 개의 피연산자가 모두 참일 때 참
	res = (a > 10) && (a < 20);
	printf("(a > 10) && (a < 20) : %d\n", res);

	//두 개의 피연산자 중 하나다로 참일 경우 참
	res = (a > 10) || (a < 20);
	printf("(a > 10) || (a < 20) : %d\n", res);

	//거짓이면 참, 참이면 거짓으로 반전
	res = !(a >= 40);
	printf("!(a >= 40) : %d\n", res);

	return 0;
}

º 실행 결과

(a > 10) && (a < 20) : 0
(a > 10) || (a < 20) : 1
!(a >= 40) : 1

* 관계 연산자 만을 사용할 때 

 

                             

                              1 단계 : a의 값에 38을 대입, 10 < 38은 참이므로 ①이 위치한 자리에 1을 대입

                              2 단계 : 1 < 20은 참이므로 해당 식의 값은 1

 

 

 

 

 

* 논리 연산자를 함께 사용할 때

 

1 단계 : 10 < a에서 a의 값 38을 대입, 10 < 38은 참이므로 ①의 자리에 1을 대입

2 단계 : a의 값 38을 대입, 38 < 20은 거짓이므로 ②의 자리에 0 대입

3 단계 : 1 && 0 은 거짓이므로 해당 식의 값은 0

 

 

º 숏 서킷 룰 : 좌항만으로 연산 결과를 판별하는 기능

 - && 연산자 : 좌항이 거짓이면 우항과 관게없이 결과는 거짓

 - || 연산자는 좌항이 참이면 우항과 관계없이 결과가 참

 

06. 연산의 결괏값을 처리하는 방법

 : 연산 결과를 바로 사용하거나 대입 연산을 통해 다른 변수에 저장 후 사용

 

★ 연산식 처리 과정

출처 : https://m.blog.naver.com/PostView.nhn?blogId=ndb796&logNo=220687216382&proxyReferer=https:%2F%2Fwww.google.com%2F

º 로드(load) : 메모리에 있는 값을 CPU의 저장 공간인 레지스터에 복사

 - 연산 명령 이전에 먼저 수행

º 스토어 (store) : 연산 장치인 ALU가 연산 후 결괏값을 레지스터에 저장 → 대입 연산 수행 후 메모리 공간에 복사하는 일련의 과정

 

 

그 외 유용한 연산자

01. 형 변환 연산자

º 피연산자가 1개 이며 피연산자의 값을 원하는 형태로 변경

(자료형)피연산자
(double)10 → 10.0

º 자동 형 변환 : 컴파일 과정에서 피연산자의 형태가 다르면 형태를 일치시키는 작업을 수행하는 것

    → 암시적인 형 변환, 묵시적인 형 변환

 - 규칙 : 크기가 작은 값이 크기가 큰 값으로 변경 ( 정수 → 실수)

    → 대입 연산 : 좌항의 변수형에 맞게 저장

 

02. sizeof 연산자

º 피연산자를 하나만 사용할 수 있으며, 연산자의 크기를 바이트 단위로 계산

sizeof(피연산자)

º 데이터의 크기를 확인하거나 메모리 동적 할당 시 사용

º sizeof 연산자와 괄호

sizeof(피연산자 + 피연산자)
sizeof(피연산자) + 피연산자

 - 두 개의 코드는 다른 결괏값을 출력

 

03. 복합대입 연산자

 : 대입 연산자의 특징을 그대로 가짐

º 왼쪽 피연산자는 반드시 변수가 위치

º 오른쪽 항의 계산이 모두 끝난 후 복합 대입 연산자는 가장 마지막에 계산

º 저장되는 공간과 연산되는 공간이 다르기 때문에 실행 가능

 

04. 콤마 연산자

 : 한 번에 여러 개의 수식을 차례로 나열해야 할 때 사용

º 왼 쪽 부터 오른쪽으로 차례로 연산 수행

º 가장 오른쪽의 피연산자가 최종 결괏값

º 대입 연산자보다 우선 순위가 낮은 연산자 → 괄호 필수

 

05. 조건 연산자

 : 유일한 삼항 연산자

º ?와 : 기호를 함께 사용

º 첫 번째 피연산자가 참이면 ? 뒤에 있는 첫 번째 피연산자가 결괏값, 거짓이면 ? 뒤에 있는 두 번째 피연산자가 결괏값

( a > b ) ? a : b

    → a > b가 참일 경우 a가 결괏값, 거짓일 경우 b가 결괏값

 

06. 비트 연산자

 : 데이터를 비트 단위로 연산

º 비트별 논리곱 연산자 ( & )

 - 0은 거짓, 1은 참

 - 두 비트가 모드 1인 경우에만 참 ( 1 )

º 비트별 배타적 논리합 연산자 ( ^ )

 - 두 비트가 서로 다른 경우에만 1로 계산

 - 둘 다 참이거나 거짓일 경우 거짓, 두 비트가 다른 경우에만 참 ( 1 )

º 비트별 논리합 연산자( | )

 - 두 비트 중에서 하나라도 참이면 참 ( 1 )

º 비트별 부정 연산자 ( ~ )

 - 참은 거짓, 거짓은 참으로 변경

 - 피연산자는 하나만 존재

º 비트 이동 연산자

 - << : 비트들을 왼쪽으로 이동

 - >> : 비트들을 오른쪽으로 이동

a << 1        //비트를 왼쪽으로 1만큼 이동
b >> 2        //비트를 오른쪽으로 2만큼 이동

 * 오른쪽으로 밀려나는 비트는 사라짐

 * 복합대입 연산자로 사용 가능

 

구분 연산자 연산 기능
비트 논리 연산자 & 두 비트가 모두 1인 경우에만 1
^ 두 비트가 서로 다른 경우만 1, 같으면 0
| 두 비트 중에서 하나라도 1일 경우 1
~ 1은 0, 0은 1
비트 이동 연산자 << 왼쪽 비트 이동 연산자
>> 오른쪽 비트 이동 연산자

 

 

07. 연산자 우선순위와 연산 방향

 : 하나의 수식에서 2개 이상의 연산자가 함께 쓰일 때, 연산자의 우선순위에 따라 연산

우선 순위 종류 연산자 연산 방향
1 1차 연산자 ( )  [ ]  .  =>
2 단항 연산자 -  ++  ==  ~  !  *  &  sizeof  (type)
3 산술 연산자 *  /  %
4 +  -
5 비트 이동 연산자 <<  >>
6 관계 연산자 <  <=  >  =>
7 동등 연산자 ==  !=
8 비트 논리 연산자 &
9 ^
10 |
11 논리 연산자 &&
12 ||
13 조건 연산자 ?  :
14 대입 연산자 =  +=  -=  *=  /=  %=  &=  ^=  |=  <<=  >>=
15 콤마 연산자 ,