C언어 이론 정리 파트 03
자료 참조 : TCP School.com
연산자(operator)
란 프로그램의 산술식이나 연산식을 표현하고 처리하기 위해 제공되는 다양한 기호를 의미한다.
C언어에서는 여러 종류의 연산을 위해 다양한 연산자를 제공하고 있다.
산술 연산자
는 사칙연산을 다루는 기본적이면서도 가장 많이 사용되는 연산자다.
산술 연산자
는 모두 두 개의 피연산자를 가지는 이항 연산자
이며, 피연산자들의 결합 방향은 왼쪽에서 오른쪽
이다.
🏷 산술 연산자 표
산술 연산자 | 설명 |
---|---|
+ | 왼쪽의 피연산자에 오른쪽의 피연산자를 더함 |
- | 왼쪽의 피연산자에서 오른쪽의 피연산자를 뺌 |
* | 왼쪽의 피연산자에 오른쪽의 피연산자를 곱함 |
/ | 왼쪽의 피연산자를 오른쪽의 피연산자로 나눔 |
% | 왼쪽의 피연산자를 오른쪽의 피연산자로 나눈 후, 그 나머지를 반환함 |
📝 예제
int num01 = 10;
int num02 = 4;
printf("+ 연산자에 의한 결괏값은 %d입니다.\n", num01 + num02); // + 연산자에 의한 결괏값은 14입니다.
printf("- 연산자에 의한 결괏값은 %d입니다.\n", num01 - num02); // - 연산자에 의한 결괏값은 6입니다.
printf("* 연산자에 의한 결괏값은 %d입니다.\n", num01 * num02); // * 연산자에 의한 결괏값은 40입니다.
printf("/ 연산자에 의한 결괏값은 %d입니다.\n", num01 / num02); // / 연산자에 의한 결괏값은 2입니다.
printf("% 연산자에 의한 결괏값은 %d입니다.\n", num01 % num02); // % 연산자에 의한 결괏값은 2입니다.
연산자의 우선순위는 수식 내에 여러 연산자가 함께 등장할 때, 어느 연산자가 먼저 처리될 것인가를 결정한다.
다음 그림은 가장 높은 우선순위를 가지고 있는 괄호() 연산자
를 사용하여 연산자의 처리 순서를 변경하는 것을 보여준다.
대입 연산자
는 변수에 값을 대입할 때 사용하는 이항 연산자
이며, 피연산자들의 결합 방향은 오른쪽에서 왼쪽이다.
또한, 앞서 살펴본 산술 연산자와 결합한 다양한 복합 대입 연산자
가 존재하다.
대입 연산자 | 설명 |
---|---|
= | 왼쪽의 피연산자에 오른쪽의 피연산자를 대입함 |
+= | 왼쪽의 피연산자에 오른쪽의 피연산자를 더한 후, 그 결괏값을 왼쪽의 피연산자에 대입함 |
-= | 왼쪽의 피연산자에서 오른쪽의 피연산자를 뺀 후, 그 결괏값을 왼쪽의 피연산자에 대입함 |
*= | 왼쪽의 피연산자에 오른쪽의 피연산자를 곱한 후, 그 결괏값을 왼쪽의 피연산자에 대입함 |
/= | 왼쪽의 피연산자를 오른쪽의 피연산자로 나눈 후, 그 결괏값을 왼쪽의 피연산자에 대입함 |
%= | 왼쪽의 피연산자를 오른쪽의 피연산자로 나눈 후, 그 나머지를 왼쪽의 피연산자에 대입함 |
📝 예제
int num01 = 7;
int num02 = 7;
int num03 = 7;
num01 = num01 - 5;
num02 -= 5;
num03 =- 5;
printf("- 연산자에 의한 결괏값은 %d입니다.\n", num01); // - 연산자에 의한 결괏값은 2입니다.
printf("-= 연산자에 의한 결괏값은 %d입니다.\n", num02); // -= 연산자에 의한 결괏값은 2입니다.
printf("=- 연산자에 의한 결괏값은 %d입니다.\n", num03); // =- 연산자에 의한 결괏값은 -5입니다.
증감 연산자는 피연산자를 1씩 증가 혹은 1씩 감소시킬 때 사용하는 연산자이다.
이 연산자는 피연산자가 단 하나뿐인 단항 연산자
다.
증감 연산자는 해당 연산자가 피연산자의 어느 쪽에 위치하는가에 따라 연산의 순서 및 결과가 달라진다.
🏷 증감 연산자 표
증감 연산자 | 설명 |
---|---|
++x | 먼저 피연산자의 값을 1 증가시킨 후에 해당 연산을 진행함 |
x++ | 먼저 해당 연산을 수행하고 나서, 피연산자의 값을 1 증가시킴 |
--x | 먼저 피연산자의 값을 1 감소시킨 후에 해당 연산을 진행함 |
x-- | 먼저 해당 연산을 수행하고 나서, 피연산자의 값을 1 감소시킴 |
📝 예제
#include <stdio.h>
int main()
{
int num01 = 7;
int num02 = 7;
int result01, result02;
result01 = (++num01) - 5;
result02 = (num02++) - 5;
printf("전위 증가 연산자에 의한 결괏값은 %d이고, 변수의 값은 %d로 변했습니다.\n", result01, num01);
// 전위 증가 연산자에 의한 결괏값은 3이고, 변수의 값은 8로 변했습니다.
printf("후위 증가 연산자에 의한 결괏값은 %d이고, 변수의 값은 %d로 변했습니다.\n", result02, num02);
// 후위 증가 연산자에 의한 결괏값은 2이고, 변수의 값은 8로 변했습니다.
}
위의 예제에서 첫 번째 연산은 변수 num01의 값을 먼저 1 증가시킨 후에 나머지 연산을 수행한다.
하지만 두 번째 연산에서는 먼저 모든 연산을 마친 후에 변수 num02의 값을 1 증가시킨다.
따라서 변수 num02의 증가는 관련된 연산에 아무런 영향도 미치지 않는다.
증감 연산자는 피연산자의 어느 쪽에 위치하는가에 따라 연산의 순서가 달라진다.
다음 예제는 증감 연산자의 연산 순서를 살펴보기 위한 예제이다.
📝 예제
#include <stdio.h>
int main()
{
int x = 10;
int y = x-- + 5 + --x;
printf("변수 x의 값은 %d이고, 변수 y의 값은 %d입니다.\n", x, y);
// 변수 x의 값은 8이고, 변수 y의 값은 23입니다.
}
연산 과정을 대충 살펴보면 꽤나 복잡하게 느껴진다.
허나 하나하나 뜯어서 보면 그렇게 복잡하지 않음을 알 수 있다.
우선 x--는 연산을 진행하고 연산자의 값을 빼기 때문에 10 + 5를 진행하고 x의 값을 1 뺴준다(x = 9)
그후에 오는 --x는 우선 연산자의 값(x = 9 - 1을 빼고 연산을 진행하기 때문에 10 + 5 + --x(x = 8)이 되서 23이 된다.
비교 연산자는 피연산자 사이의 상대적인 크기를 판단
하는 연산자다.
비교 연산자
는 왼쪽의 피연산자와 오른쪽의 피연산자를 비교하여, 어느 쪽이 더 큰지, 작은지, 또는 서로 같은지를 판단한다.
비교 연산자는 모두 두 개의 피연산자를 가지는 이항 연산자이며, 피연산자들의 결합 방향은 왼쪽에서 오른쪽(->)이다.
🏷 비교 연산자 표
비교 연산자 | 설명 |
---|---|
== | 왼쪽의 피연산자와 오른쪽의 피연산자가 같으면 1을 반환함 |
!= | 왼쪽의 피연산자와 오른쪽의 피연산자가 같지 않으면 1을 반환함 |
> | 왼쪽의 피연산자가 오른쪽의 피연산자보다 크면 1을 반환함 |
>= | 왼쪽의 피연산자가 오른쪽의 피연산자보다 크거나 같으면 1을 반환함 |
< | 왼쪽의 피연산자가 오른쪽의 피연산자보다 작으면 1을 반환함 |
<= | 왼쪽의 피연산자가 오른쪽의 피연산자보다 작거나 같으면 1을 반환함 |
거짓(false)
은 0이며, 0이 아닌 모든 것은 참(true)
으로 인식된다. 즉 위의 표에서 1을 반환하는 것은 참(True)을 반환하는 것으로 봐도된다.📝 예제
#include <stdio.h>
int main()
{
int num01 = 3;
int num02 = 7;
printf("== 연산자에 의한 결괏값은 %d입니다.\n", num01 == num02);
// == 연산자에 의한 결괏값은 0입니다.
printf("<= 연산자에 의한 결괏값은 %d입니다.\n", num01 <= num02);
// <= 연산자에 의한 결괏값은 1입니다.
}
논리 연산자는 주어진 논리식을 판단하여, 참(true)
과 거짓(false)
을 결정하는 연산자이다.
AND 연산과 OR 연산은 두 개의 피연산자를 가지는 이항 연산자이며, 피연산자들의 결합 방향은 왼쪽에서 오른쪽이다.
NOT 연산자는 피연산자가 단 하나뿐인 단항 연산자이며, 피연산자의 결합 방향은 오른쪽에서 왼쪽이다.
🏷 논리 연산자(AND, OR, NOT) 표
논리 연산자 | 설명 |
---|---|
&& | 논리식이 모두 참이면 1을 반환함. (논리 AND 연산) |
ll | 논리식 중에서 하나라도 참이면 1을 반환함. (논리 OR 연산) |
! | 논리식의 결과가 참이면 0을, 거짓이면 1을 반환함. (논리 NOT 연산) |
🏷 논리 연산자 진리표
A | B | A && B | A ㅣㅣ B(OR) | !A |
---|---|---|---|---|
1 (true) | 1 (true) | 1 (true) | 1 (true) | 0 (false) |
1 (true) | 0 (false) | 0 (false) | 1 (true) | 0 (false) |
0 (false) | 1 (true) | 0 (false) | 1 (true) | 1 (true) |
0 (false) | 0 (false) | 0 (false) | 0 (false) | 1 (true) |
📝 예제
#include <stdio.h>
int main()
{
int num01 = 3;
int num02 = -7;
int result01, result02;
result01 = (num01 > 0) && (num01 < 5);
result02 = (num02 < 0) || (num02 > 10);
printf("&& 연산자에 의한 결괏값은 %d입니다.\n", result01);
// && 연산자에 의한 결괏값은 1입니다.
printf("|| 연산자에 의한 결괏값은 %d입니다.\n", result02);
// || 연산자에 의한 결괏값은 1입니다.
printf(" ! 연산자에 의한 결괏값은 %d입니다.\n", !result02);
// ! 연산자에 의한 결괏값은 0입니다.
}
비트 연산자는 비트(bit) 단위로 논리 연산을 할 때 사용하는 연산자이다.
또한, 비트 단위로 전체 비트를 왼쪽이나 오른쪽으로 이동시킬 때도 사용한다.
🏷비트 연산자 표
비트 연산자 | 설명 |
---|---|
& | 대응되는 비트가 모두 1이면 1을 반환함. (비트 AND 연산) |
l | 대응되는 비트 중에서 하나라도 1이면 1을 반환함. (비트 OR 연산) |
^ | 대응되는 비트가 서로 다르면 1을 반환함. (비트 XOR 연산) |
~ | 비트를 1이면 0으로, 0이면 1로 반전시킴. (비트 NOT 연산) |
<< | 지정한 수만큼 비트들을 전부 왼쪽으로 이동시킴. (left shift 연산) |
>> | 부호를 유지하면서 지정한 수만큼 비트를 전부 오른쪽으로 이동시킴. (right shift 연산) |
다음 그림은 비트 AND 연산자(&)
의 동작을 나타낸다.
비트 AND 연산자
는 대응되는 두 비트가 모두 1일 때만 1을 반환하며, 다른 경우는 모두 0을 반환한다.
다음 그림은 비트 OR 연산자(|)
의 동작이다.
비트 OR 연산자
는 대응되는 두 비트 중 하나라도 1이면 1을 반환하며, 두 비트가 모두 0일 때만 0을 반환한다.
다음 그림은 비트 XOR 연산자(^)
의 동작을 나타낸다.
이처럼 비트 XOR 연산자
는 대응되는 두 비트가 서로 다르면 1을 반환하고, 서로 같으면 0을 반환합니다.
다음 그림은 비트 NOT 연산자(~)
의 동작을 나타낸다.
이처럼 비트 NOT 연산자
는 해당 비트가 1이면 0을 반환하고, 0이면 1을 반환한다.
📝 예제
#include <stdio.h>
int main()
{
int num01 = 15; int num02 = 8;
printf(" ~ 연산자에 의한 결괏값은 %d입니다.\n", ~num01); // 1의 보수
// ~ 연산자에 의한 결괏값은 -16입니다.
printf("<< 연산자에 의한 결괏값은 %d입니다.\n", num02 << 1); // 곱하기 2
// << 연산자에 의한 결괏값은 16입니다.
printf(">> 연산자에 의한 결괏값은 %d입니다.\n", num02 >> 1); // 나누기 2
// >> 연산자에 의한 결괏값은 4입니다.
}
이 연산자는 C언어에서도 유일하게 피연산자를 세 개나 가지는 조건 연산자이다.
자바스크립트에서도 사용하는 연산자인데 C언어에서 파생된 듯 하다.
✅ 문법
조건식 ? 반환값1 : 반환값2
물음표(?) 앞의 조건식에 따라 결괏값이 참(true)이면 반환값1을 반환하고, 결괏값이 거짓(false)이면 반환값2를 반환한다.
반환값에는 값뿐만 아니라 수식, 함수 호출 등 여러 가지 형태의 명령문이 올 수 있다.
📝 예제
int num01 = 15;
int num02 = 8;
int result;
result = (num01 > num02) ? num01 : num02;
printf("둘 중에 더 큰수는 %d입니다.\n", result); // 둘 중에 더 큰수는 15입니다.
삼항 연산자는 짧은 if / else 문 대신에 사용할 수 있으며, 코드를 간결하게 작성할 수 있도록 도와준다.
쉼표(,) 연산자
는 얼핏 연산자가 아닌 것처럼 보이지만 다양한 용도로 사용되는 연산자입니다.
이 연산자는 어떠한 연산을 수행하는 것이 아니라 다음과 같은 상황에서 사용됩니다.
두 연산식을 하나의 연산식으로 나타내고자 할 때
둘 이상의 인수를 함수로 전달하고자 할 때
📝 예제
int num01 = 15, num02 = 8;
printf("첫 번째 수는 %d이고, 두 번째 수는 %d입니다.\n", num01, num02); // 첫 번째 수는 15이고, 두 번째 수는 8입니다.
위의 예제에서 쉼표 연산자는 둘 이상의 변수를 동시에 선언하기 위해서 사용되었다.
또한, printf() 함수에서는 둘 이상의 인수를 동시에 printf() 함수로 전달하기 위해서 사용되었다.
사용자의 컴퓨터 환경에 따라 타입에 할당되는 메모리의 크기가 달라질 수 있다.
sizeof 연산자는 단항 연산자로 피연산자의 크기를 바이트 단위로 반환한다.
이 연산자는 피연산자로 타입뿐만 아니라 변수나 상수를 전달받을 수도 있다.
sizeof 연산자에 변수나 상수가 피연산자로 전달되면, 해당 변수나 상수에 해당하는 타입의 크기를 반환해 준다.
📝 예제
#include <stdio.h>
int main()
{
int num01 = 15;
int num02 = 8;
printf(" num01의 크기는 %d입니다.\n", sizeof(num01));
// num01의 크기는 4입니다.
printf(" num02의 크기는 %d입니다.\n", sizeof(num02));
// num01의 크기는 4입니다.
}
C언어에서 포인터와 연관되어 사용되는 연산자는 다음과 같다.
주소 연산자(&)
참조 연산자(*)
주소 연산자(&)
는 변수의 이름 앞에 사용하여, 해당 변수의 주소값을 반환한다.
'&'기호
는 앰퍼샌드(ampersand)
라고 읽으며, 번지 연산자
라고도 불린다.
참조 연산자(*)
는 포인터의 이름이나 주소 앞에 사용하여, 포인터에 가리키는 주소에 저장된 값을 반환한다.
C언어에서 *기호
는 사용하는 위치에 따라 다양한 용도로 사용된다.
이항 연산자로 사용하면 곱셈 연산으로 사용되며, 포인터의 선언 시나 메모리에 접근할 때도 사용된다.