연산자가 뭐가 다르겠나.. JAVA나 Python, C나 그게 그거지라고 했다가는 알아야 할 것도 다 놓치기에 오랜만에 한 번 더 보고 넘어간다.
연산자 : 연산에 사용되는 기호
피연산자 : 연산의 대상이 되는 값
수식(expression) : 연산자와 피연산자의 조합
모든 수식에는 반드시 값이 있고, 수식의 값을 구하는 것을 '수식을 평가(evaluate)한다' 라고 한다.
상수나 변수/연산자가 포함된 연산식도 수식이다. 리턴 값이 있는 함수 호출도 수식으로 볼 수 있다.
연산자를 이용하는 수식은 연산자와 하나 이상의 피연산자로 이뤄진다.
연산에 사용되는 기호를 연산자라고 하며 C언어는 다양한 종류의 연산자를 제공한다.
연산자는 피연산자의 개수에 따라서 단항 연산자(unary operator), 이항 연산자(binary operator), 삼항 연산자(ternary operator)로 분류가능하다.
뭐야 다 아는 내용이네? 해도 벼는 익을수록 고개를 숙인다지 않는가.
의자에 앉아서 허리 굽는 거랑 다른 거니까 한번 더 보자.
산술 연산자 | 의미 | 사용 예 | 연산 결과 |
+a | 플러스(부호) | +10 | 10 |
-a | 마이너스(부호) | -10 | -10 |
a + b | 더하기 | 10 + 3 | 13 |
a - b | 빼기 | 10 - 3 | 7 |
a * b | 곱하가ㅣ | 10 * 3 | 30 |
a / b | 나누기 | 10 / 3 | 3 |
a % b | 나머지 구하기 | 10 % 3 | 1 |
# 나머지 연산자(%)는 피연산자가 모두 정수인 경우에만 사용할 수 있다.
++ 나누기나 나머지 여난자의 우변은 0이 될 수 없다.
만일 0으로 나누거나 0으로 나머지 연산을 수행하면 프로그램이 비정상 종료된다.
%를 출력하려면 %%로 입력해야한다.
실수에 대해 나머지 연산자를 사용하려고 하면 컴파일 에러가 발생한다.
산술 연산 시 피연산자의 형 변환 규칙
1. 피연산자 중에 double형이 있으면, 나머지 피연산자를 double형으로 변환한다.
1.25 * 3 //double * double로 처리
1.25 + 0.5F //double + double로 처리
2. 피연산자 중에 float형이 있으면, 나머지 피연산자(정수형)를 float형으로 변환한다.
1.25F / 2 //float / float로 처리
3. 피연산자가 둘 다 정수형이면 우선 승격한다. 즉, char형이나 short형을 int형으로 변환한다. 승격 후 피연산자가 같은 형이면 그대로 연산한다.
short a = 1000, b = 2000;
a * b //int * int로 처리
4. 피연산자의 signed/unsigned 여부가 일치하면, 작은 형을 큰형으로 변환한다.
'a' + 10L // long + long으로 처리
5. 피연산자의 signed/unsinged 여부가 일치하지 않고, unsigned형의 크기가 signed형의 크기보다 크거나 같으면, unsigned형 쪽으로 맞춰 변환한다.
short a = 100;
123U - a // unsigned int - unsigned int으로 처리
6. 피연산자의 signed/unsigned 여부가 일치하지 않고 unsigned형의 크기가 signed형의 크기보다 작으면, signed형 쪽으로 맞춰 변환한다.
123U + 1234567LL // long long + long long으로 처리
피연산자가 하나인 단항 연산자에서는 항상 정수의 승격이 일어난다.
정수와 실수의 혼합 연산 시 수행되는 형 변환은 자동 처리된다.
자동 형 변환/ 암시적인 형 변환(implicit type conversion)이라고 한다.
증감 연산자
: 변수의 값을 1만큼 증가시키거나 감소시키는 단항 연산자
++연산자는 변수의 값을 1만큼 증가시키고, -- 연산자는 변수의 값을 1만큼 감소시킨다.
증감 연산자는 반드시 변수에만! 코드를 어느 정도 다뤄본 사람이라면 당연하듯이 쓰고 있을 것이다.
구분 | 증감 연산자 | 수식의 값 |
전위형 | ++a | 증가된 변수 a의 값 |
--a | 감소된 변수 a의 값 | |
후위형 | a++ | 증가되기 전 변수 a의 값 |
a-- | 감소되기 전 변수 a의 값 |
증감 연산자를 통한 소스 코드의 길이를 줄이는 것은 프로그램 성능과는 관련이 없기 때문에 코드를 명확하게 작성하자!
대입 연산자
: 연산자의 좌변에 있는 변수에 우변의 값을 저장
대입 연산자의 좌변에 있는 변수의 값이 대입 연산식의 값이 된다.
복합 대입 연산자
대입 연산자는 산술 연산자, 비트 연산자와 합쳐서 복합 대입 연산자로 사용할 수 있다.
복합 대입 연산자는 좌변의 변수를 피연산자로 이용해서 연산을 수행하고 연산의 결과를 다시 좌변의 변수에 대입한다.
복합 대입 연산자 | 의미 | 복합 대입 연산자 | 의미 |
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 | 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 |
관계 연산자
: 두 수의 값을 비교하기 위한 연산자
항상 참 또는 거짓이 된다.
C에서 참(true)은 1이고, 거짓(false)은 0이다.
관계 연산자 | 의미 | a = 1, b = 2일 때 연산의 결과 |
a > b | a가 b보다 큰가? | 0 |
a >= b | a가 b보다 크거나 같은가? | 0 |
a < b | a가 b보다 작은가? | 1 |
a <= b | a가 b보다 작거나 같은가? | 1 |
a == b | a가 b와 같은가? | 0 |
a != b | a가 b와 다른가? | 1 |
관계 연산자 사용 시 주의 사항
값의 비교를 위해서는 =가 아니라 ==를 이용해야 한다.
실수를 비교할 때는 오차를 고려하여, 부동소수점 방식의 실수는 수치와 가장 가까운 근삿값으로 반올림된다.
때문에 연산의 결과로 만들어지는 실수 값을 직접 비교해서는 안된다.
C에서는 수식이 참인지 거짓인지 판단할 때, 0이 아닌 값은 참으로 간주한다.
관계 연산자는 2항 연산자로 한 번에 2개의 값만 비교할 수 있다.
예로 10<x<20을 C에서 비교하려면 10<x && x<20으로 표현해야 한다.
논리 연산자
: 참과 거짓을 이용한 논리 연산 기능을 제공
논리 연산자 | 부울 대수 | 의미 |
a && b (이항 연산자) | 논리 AND | a와 b가 둘 다 0이 아니면 1 a와 b중 하나만 0이면 0 |
a || b (이항 연산자) | 논리 OR | a와 b중 하나만 0이 아니면 1 a와 b가 둘 다 0이면 0 |
! a (단항 연산자) | 논리 NOT | a가 0이면 1,a가 0이 아니면 0 |
논리 연산자의 결과는 항상 참(1)이나 거짓(0)이다.
C에서는 0이 아닌 값은 참으로 간주하므로 &&, ||, !의 피연산자가 0이 아니면 참으로 논리연산이 수행
논리연산자 &&, ||를 관계 연산자와 함께 사용하면 관계 연산자부터 수행된다.,
&& 연산자가 || 연산자보다 우선순위가 높다.
논리 연산자의 단축계산
: 논리연산자를 포함한 수식을 평가할 때는 우선 피연산자를 좌변, 우변의 순서로 평가하고 전체 수식을 평가하기 때문에 &&와 || 연산자는 우변이 논리연산자의 특징에 따라 수행되지 않는 경우가 있다.
비트 연산자
: 피연산자의 각 비트 단위로 수행되는 연산자
비트 연산자
구분 | 비트 연산자 | 의미 |
비트 논리 연산자 | a & b | a와 b의 각 비트 단위로 논리 AND 연산 |
a | b | a와 b의 각 비트 단위로 논리 OR 연산 | |
a ^ b | a와 b의 각 비트 단위로 논리 XOR 연산 | |
~a | a의 각 비트 단위로 논리 NOT 연산 | |
비트 이동 연산자 | a << b | a의 각 비트를 b만큼 왼쪽으로 이동 |
a >> b | a의 각 비트를 b만큼 오른쪽으로 이동 |
간혹 XOR연산의 이해가 혼동되는 사람들을 위해,
OR 연산이 둘 중 하나라도 1이면 1이지만, XOR 연산은 둘 중 하나만이 1이어야 1이다.
즉, 피연산자가 서로 다른 값이면 1, 같은 값이면 0이다.
TMI지만 0은 1로, 1은 0으로 바꾸는 것을 토글이라고 한다.
toggle key는 한영, caps, num lock, insert가 있다.
당연한 얘기지만 데이터형이 일치하지 않으면, 형 변환이 진행된 후에 연산을 진행한다.
두둥탁 나머지 연산자
삼항연산자(?:)
num1>num2 ? x : y 의 경우 num1이 num2보다 크면 x가 할당되며 num1이 num2보다 작을 경우는 y가 할당되는 것이다.
콤마연산자(,)
다들 잘 알겠지만 나열용이다.
형 변환 연산자
1) 암시적인 형 변환(자동 형 변환)
: 따로 지정하지 않아도 자연스럽게 수행되는 형 변환
(char형이나 short형의 값이 사용될 때마다 자동으로 int형으로 형 변환되는 것을 정수의 승격이라고 하는데,
정수의 승격 또한 자동으로 수행되므로 암시적인 형 변환이다)
2) 명시적인 형 변환
:수식 앞에 데이터형을 ()와 함께 적어주는데, 이것을 형 변환 연산자(type cast operator)라고 한다.
실수에서 나누기 연산을 진행함에 있어 명시적인 형변환은 필수적이다.
연산자의 우선순위
단항 > 산술 > 관계 > 논리 > 대입 > 콤마
순서는 위처럼 되어있지만, 쓰다 보면 자연스럽게 알게 되니 암기한다는 생각보다는 많이 접해야지라는 생각으로 임하는 것이 좋다.
대강 이렇구나라는 느낌만 알면 된다.
연산자의 결합 규칙
대부분 좌에서 우로 진행되지만, 다항 연산자와 대입 연산자는 우에서 좌로 진행된다.
이것 또한 마찬가지로 JAVA나 Python과 같이 다른 랭귀지로 똑같기에 그냥 그렇구나 하면 된다.
많이 접해보면 자연스럽게 이게 이소리구나 알게 된다.
책 한 권 일주일 만에 떼기 목표로 잡았는데 너무 힘들다 흐헣 죽겄다
'Language & Framework & GIT > C' 카테고리의 다른 글
[씨앤씨뿔] C/ 함수 (0) | 2023.04.04 |
---|---|
[씨앤씨뿔] C/ 제어문 (0) | 2023.03.28 |
[씨앤씨뿔]C/ 데이터형&연산자 (0) | 2023.03.25 |
[씨앤씨뿔]C/ C 구성 요소 (0) | 2023.03.23 |
[씨앤시뿔] C/ C? (2) | 2023.03.23 |
댓글