C언어(학점아님)/c언어 개념

3-1. 연산자

오버헤드프레스 2023. 3. 18. 16:17

산술 연산자, 관계 연산자, 논리 연산자

 

산술 연산자는 더하기(+), 빼기(-), 곱하기(*), 나누기(/), 나머지(%)가 있다.

이 중 -연산자는 피연산자를 하나만 사용할 때 피연산자의 부호를 바꾸는 역할도 한다.

ex) 1+a, a+b라는 문장에서 +는 연산자, 1, a, b는 피연산자이다.

 

예제로 대입, 더하기, 빼기, 곱하기 연산자를 먼저 보자.

 

#include <stdio.h>

int main(void)
{
	int a, b;
	int sum, sub, mul, inv;
	
	a = 10;               //대입 연산(=) 
	b = 20;               //대입 연산(=)
	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, b는 대입 연산자를 통해 수를 대입한 후 각 연산자에 식을 대입해 printf로 값을 출력했다.

이와 같이 연산자를 통해 계산이 가능하다.

 

 

대입 연산자

 

변수에서도 = 기호를 다뤘다. =는 대입 연산자라 하며 오른쪽 수식의 결과를 왼쪽 변수에 저장한다.

여기서 수식은 상수나 변수, 연산자를 사용한 식을 모두 포함한다.

 

a = 10;
b = 20;

대입 연산자는 변수의 값을 바꾸므로 이후에 a와 b의 값은 각각 10과 20이 된다.

대입 연산자와 다른 연산자와 함께 사용할 경우 우선순위에 따른 다른 연산을 먼저 수행하고 그 결과를 왼쪽 변수에 저장한다.

연산자 우선순위는 마지막에 표로 올려놓겠다.

 

 

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

 

나누기는 / 연산자를 사용한다. 나누기 연산자는 피연산자의 형태에 따라 결과가 달라지니 주의하자.

정수로 연산할 때는 몫을 구하고 실수로 연산할 때는 소수점까지 구한다.

 

예제를 통해 알아보자.

 

#include <stdio.h>

int main(void)
{
	double apple;  //실수
	int banana;    //정수
	int orange;    //정수
	
	apple = 5.0 / 2.0;   //실수와 실수의 나누기 연산 
	banana = 5 / 2;      //정수와 정수의 나누기 연산 
	orange = 5 % 2;      //정수와 정수의 나머지 연산(%) 
	
	printf("apple : %.1f\n", apple);
	printf("banana : %d\n", banana);
	printf("orange : %d\n", orange);
	 
	return 0;
}

 

apple의 값은 예상대로 2.5가 나왔다.

나누기 연산자의 피연산자가 모두 실수이므로 소수점까지 계산되어 결과는 2.5가 된다.

 

그런데 banana의 출력값은 2다. 피연산자가 모두 정수이므로 몫만 계산되었다.

 

이와 같이 나눗셈 연산자는 정수, 실수가 될 수 있기에 그 값을 저장하는 변수도 그에 맞게 사용해야 한다.

apple은 실수이므로 double형 변수에, banana의 연산결과는 정수이므로 int형 변수에 저장한다.

 

마지막으로 몫을 뺀 나머지만 구할 때는 나머지 연산자인 %를 사용한다. 

실수 연산에는 나머지의 개념이 없으므로 나머지 연산자의 피연산자로는 반드시 정수만을 사용한다.

 

 

증감 연산자

 

a라는 int형 변수에 1을 더하려면 a = a + 1;이라고 쓸 것이다. 하지만 다른 방법으로 사용할 수 있다.

                                       

                                          ++a (증가 연산자), --a (감소 연산자)

 

이 표현은 앞으로 for문, while문, do while문 같은 반복문에서 자주 사용된다.

증감 연산자는 단항 연산자로 피연산자의 값을 1 증가시키거나 1 감소시킨다.

 

예제를 통해 더 알아보자.

 

#include <stdio.h>

int main(void)
{
	int a = 10, b = 10;
	
	++a;         //변수의 값을 1만큼 증가 
	--b;         //변수의 값을 1만큼 감소 
	 
	printf("a : %d\n", a);    
	printf("b : %d\n", b);
	 
	return 0;
}

a = 10; 을 ++a로 1을 더해줘 11이 나왔으며, b = 10; 을 --b로 1 빼줘 9가 나왔다.

증감 연산자의 피연산자로 상수를 이용할 수 없다.

 

 

전위 표기와 후위 표기

 

증감 연산자가 피연산자 앞에 놓이면 전위 표기, 피연산자 뒤에 놓이면 후위 표기라고 한다.

쓰임이 다르기 때문에 예제로 바로 알아보자.

 

#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와 a++는 a의 값을 1씩 증가시킨다. 그러나 다른 연산자와 함께 쓰인다면 다른 연산의 결과에 영향을 미친다.

 

(++a) * 3은 a의 값을 6으로 증가한 후에 3과 곱하므로 결괏값은 18이다.

(b++) * 3은 b가 증가되기 전의 값을 3과 곱하기 때문에 결괏값은 15이다.

물론 연산이 끝난 후에 a와 b의 값은 모두 1씩 증가된다.

a++ 형태의 증감 연산자는 다른 연산자와 함께 사용될 때 가장 마지막에 계산한다.

 

 

관계 연산자

 

관계 연산자에는 대소 관계 연산자와 동등 관계 연산자가 있다.

< , > : 대소 관계를 나타낼 때

==(같다), !=(같지 않다) : 동등 관계를 나타낼 때

이들 연산자는 모두 피연산자를 2개 사용하며, 연산의 결괏값은 0, 1이다.

(컴퓨터는 0을 거짓(false), 0이 아닌 값은 참(true)으로 판단한다.

 

예제를 통해 알아보자.

 

#include <stdio.h>

int main(void)
{
	int a = 10, b = 20;
	int res;  // 결과값을 저장할 변수
	          //각각 a와 b를 대입해보자.
			  
	res = (a > b);   //10 > 20은 거짓이므로 결과값은 0
	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 == b);
	printf("a == b : %d\n", res);
	
	res = (a != b);
	printf("a != b : %d\n", res);
	 
	return 0;
}

a > b는 거짓이기에 0, a >= b 또한 거짓이기에 0

a < b는 참이기에 1, a <= b는 참이기에 1

a == b는 거짓이기에 0, a != b는 참이기에 1

 

많이 헷갈리는 부분은 a = 5, a == 5인데 =는 a에 5를 대입하는 것이고, a == 5는 a가 5랑 같은지를 물어보는 것이다.

또한 >=를 =>로 표기하거나 <= 를 =<로 표기하면 컴파일 에러가 난다.

 

 

논리 연산자

 

논리 연산자는 참과 거짓을 판단하는 데 사용하며 &&(AND), ||(OR), !(NOT) 셋뿐이다.

&&는 논리곱으로 2개의 피연산자가 모두 참일 때만 연산결과가 참이 된다.

||는 논리합으로 둘 중 하나라도 참이면 참이 된다.

!는 논리부정으로 피연산자를 하나 사용하여 그 참과 거짓을 바꿀 때 사용한다.

예제를 통해 살펴보자.

 

#include <stdio.h>

int main(void)
{
	int a = 30;
	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 >= 30);                   //거짓이면 참으로, 참이면 거짓으로 
	printf("!(a >= 30) : %d\n", res);
	 
	return 0;
}

결괏값은 다음과 같다.

여기서 res = (a > 10) && (a < 20); 을 10 < a < 20으로 표현할 수 있지 않는가라고 생각하면 큰일 난다.

 

10 < a < 20을 살펴보자. 10 < a 가 우선 연산되니 값은 1이다. 그럼 1 < 20은 참이기에 결과 출력은 1로 된다.

(10 < a) && (a < 20)을 살펴보자. 10 < a는 a가 30이기에 참으로 1이 나온다. a < 20은 거짓으로 0이 나오는데

1 && 0 은 거짓이므로 해당 식의 값은 0이 된다.

 

이처럼 두 경우는 전혀 다른 결과를 도출하므로 수식을 만들 때 늘 유의하자.

 

 

숏 서킷 룰

 

&&와 || 연산자에는 숏 서킷 롤이 적용된다. 숏 서킷 룰이란 좌항만으로 &&와 ||의 연산 결과를 판별하는 기능이다.

예를 들어 && 연산자에서 좌항이 거짓이면 우항과 관계없이 결과는 거짓이다.

||연산자는 좌항이 참이면 우항과 관계없이 참이다.

이처럼 &&, ||연산자에서 좌항이 거짓이거나 참이면 우항은 아예 실행되지 않는다.

 

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

연산을 실행한 다음 연산의 결괏값을 변수에 저장하지 않으면 버려진다.

따라서 연산 결과를 곧바로 사용하거나 대입 연산을 통해 다른 변수에 저장해야 한다.

예제를 통해 알아보자.

 

#include <stdio.h>

int main(void)
{
	int a = 10, b = 20, res;
	
	a + b;                                    //연산 결과는 버려짐 
	printf("%d + %d = %d\n", a, b, a + b);    //연산 결과를 바로 출력에 사용 
	
	res = a + b;                              //연산 결과를 변수에 저장 
	printf("%d + %d = %d\n", a, b, res);      //저장된 값을 계속 사용 
	 
	return 0;
}

똑같은 값이 출력되나 a + b;는 연산 결과가 버려지고, res = a + b;는 변수에 연산 결과를 저장하니 알맞게 사용하자.

 

마지막으로 연산의 우선순위를 보고 3-1은 마무리하도록 하겠다.

 

출처 :https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=james_parku&logNo=110166235105

연산자의 우선순위는 중요하니 꼭 숙지하자.

 

3-2에서 연산자를 이어하겠다.

'C언어(학점아님) > c언어 개념' 카테고리의 다른 글

5. 반복문  (0) 2023.03.19
4. 선택문(if, switch ~ case)  (0) 2023.03.19
3-2. 그 외의 연산자  (0) 2023.03.18
2. 변수와 데이터 입력  (0) 2023.03.14
1. 상수와 데이터 출력  (0) 2023.03.14