비트와 여러 연산자
조건 연산자 (Conditional Operator)
C 언어에서 유일하게 3개의 **Operand(피연산자)**를 갖는 삼항 연산자이다. 이 연산자는 ?
와 :
두 개의 기호로 구성된다.
문법: exp1 ? exp2 : exp3
exp1
이 참(0이 아닌 값)으로 평가되면, 전체 연산식의 결과는exp2
의 값이 된다.exp1
이 거짓(0)으로 평가되면, 전체 연산식의 결과는exp3
의 값이 된다.
예를 들어, max = (a > b) ? a : b;
문장은 a
가 b
보다 크면 max
에 a
를, 그렇지 않으면 b
를 할당한다. 이는 if-else
문을 간결하게 표현하는 방법이다.
비트 논리 연산자 (Bitwise Logical Operators)
**Bitwise Logical Operator(비트 논리 연산자)**는 정수 값을 비트 단위로 논리 연산을 수행하는 연산자이다.
연산자 | 기호 | 의미 |
---|---|---|
AND | & | 두 피연산자의 각 비트에 대해 AND 연산을 수행한다. |
OR | ` | ` |
XOR | ^ | 두 피연산자의 각 비트에 대해 XOR 연산을 수행한다 (두 비트가 다를 때 1). |
Complement | ~ | 단일 피연산자의 모든 비트를 반전시킨다 (1의 보수). |
비트 연산 진리표:
| 비트 x
| 비트 y
| x & y
| x | y
| x ^ y
| ~x
|
| -------- | -------- | ------- | ------- | ------- | ---- |
| 0 | 0 | 0 | 0 | 0 | `` |
| 0 | 1 | 0 | 1 | 1 | 1 |
| 1 | 0 | 0 | 1 | 1 | 0 |
| 1 | 1 | 1 | 1 | 0 | 0 |
예를 들어, 3 & 5
연산은 각 숫자의 32비트 이진수 표현에 대해 비트별 AND 연산을 수행한다. 3
(00...011)과 5
(00...101)를 AND 연산하면 1
(00...001)이 된다.
이동 연산자 (Shift Operators)
**Shift Operator(이동 연산자)**는 변수의 비트들을 지정된 횟수만큼 왼쪽 또는 오른쪽으로 이동시킨다.
연산자 | 기호 | 의미 |
---|---|---|
왼쪽 이동 | << | 비트를 왼쪽으로 이동시킨다. |
오른쪽 이동 | >> | 비트를 오른쪽으로 이동시킨다. |
- 왼쪽 이동 (
<<
): 비트들을 왼쪽으로 이동시키고, 왼쪽 경계를 벗어나는 비트는 버려진다. 오른쪽의 빈자리는 모두 0으로 채워진다.a << b
연산은a
에2^b
를 곱하는 효과와 같다. - 오른쪽 이동 (
>>
): 비트들을 오른쪽으로 이동시키고, 오른쪽 경계를 벗어나는 비트는 버려진다. 왼쪽의 빈자리는 원래 숫자의 부호 비트(최상위 비트)로 채워진다. 만약 피연산자가 양수라면a >> b
연산은a
를2^b
로 나누는 효과와 같다.
비트 마스크 (Bit Mask)
**Bit Mask(비트 마스크)**는 특정 비트들만 선택하거나 변경하기 위해 사용하는 상수나 변수이다.
- 특정 비트 값 확인: 확인하려는 비트 위치만 1이고 나머지는 0인 마스크를 만들어
&
연산을 수행한다. 예를 들어, 변수a
의 n번째 비트를 확인하는 일반식은(a & (1 << (n-1)))
이다. - 특정 비트 값 변경:
- 비트를 1로 설정:
|
연산을 사용한다. - 비트를 0으로 설정: 해당 비트만 1인 마스크를
~
로 반전시킨 후&
연산을 사용한다. - 비트 반전(toggle):
^
연산을 사용한다.
- 비트를 1로 설정:
기타 연산자
sizeof
연산자
sizeof
는 변수나 자료형이 메모리에서 차지하는 크기를 바이트 단위로 반환하는 연산자이다. sizeof(자료형)
또는 sizeof 변수명
형태로 사용하며, 자료형에는 괄호가 필수이다.
형변환 연산자 (Type Casting)
C언어는 연산 시 자료형이 다른 피연산자들을 하나의 통일된 자료형으로 자동 변환한다. 크기가 작은 형에서 큰 형으로 변환되는 것을 **Promotion(형 넓히기)**이라고 한다.
반대로, 큰 형에서 작은 형으로 변환(형 좁히기)할 때는 정보 손실이 발생할 수 있다. Type Casting(형변환) 연산자 (자료형)
를 사용하여 명시적으로 자료형을 변환할 수 있다.
int x = 6, y = 4;
double result;
result = (double)x / y; // result는 1.5가 된다. x를 double로 형변환 후 나눗셈 수행.
result = x / y; // result는 1.0이 된다. 정수 나눗셈 후 결과를 double로 저장.
축약 대입 연산자 (Compound Assignment Operator)
+=
, -=
, *=
등은 산술/비트 연산과 대입 연산을 결합한 형태이다. 예를 들어, x += y
는 x = x + y
와 동일한 의미를 가진다.
콤마 연산자 (Comma Operator)
콤마 연산자
는 우선순위가 가장 낮다. 왼쪽에서 오른쪽으로 연산을 수행하며, 전체 연산식의 결과값은 가장 마지막에 수행된 연산의 결과가 된다.
-
x = 3+4, 5-10;
: 대입 연산자가 콤마보다 우선순위가 높아x = 7
이 먼저 수행되고,5-10
은 의미 없는 구문이 된다. -
x = (3+4, 5-10);
: 괄호 안의 콤마 연산자가 먼저 수행된다.3+4
가 수행된 후5-10
이 수행되고, 마지막 결과인-5
가x
에 대입된다.
연산자 우선순위
C 언어의 연산자는 정해진 **Operator Precedence(연산자 우선순위)**에 따라 평가된다. 일반적으로 우선순위는 다음과 같다:
- 괄호
()
, 배열[]
, 구조체.
->
- 단항 연산자 (
++
,--
,!
,~
,sizeof
) - 산술 연산자 (
*
,/
,%
,+
,-
) - 이동 연산자 (
<<
,>>
) - 관계 연산자 (
<
,>
,<=
,>=
) - 등가 연산자 (
==
,!=
) - 비트 논리 연산자 (
&
,^
,|
) - 논리 연산자 (
&&
,||
) - 조건 연산자 (
?:
) - 대입 연산자 (
=
,+=
,-=
, 등) - 콤마 연산자 (
,
)
조건문
조건문은 특정 조건을 만족할 때만 해당하는 코드를 실행하도록 제어하는 문장이다.
if
문
**if statement(if 문)**는 주어진 표현식(expression)이 참(0이 아닌 값)일 경우에만 뒤따르는 문장(statement)을 실행한다. 여러 문장을 실행하려면 중괄호{}
로 묶어야 한다.
if (grade >= 4.3) {
printf("장학금을 받습니다.\n");
}
if-else
문
else
키워드를 사용하면 if
문의 표현식이 거짓일 경우 실행할 문장을 지정할 수 있다.
if (number % 2 == 0) {
printf("짝수(even) 입니다.\n");
} else {
printf("홀수(odd) 입니다.\n");
}
중첩된 if
와 else if
문
중첩된 if 문은 if
문 내부에 또 다른 if
문이 포함된 구조이다. 이 때 else
는 자신과 가장 가까운 if
와 연결되므로, 의도치 않은 동작을 피하기 위해 중괄호{}
를 명확히 사용하는 것이 중요하다.
여러 조건을 순차적으로 검사할 때는 else if
구조를 사용하는 것이 더 명확하다.
if (point >= 90) {
printf("학점은 A입니다.\n");
} else if (point >= 80) {
printf("학점은 B입니다.\n");
} else {
printf("학점은 C 이하입니다.\n");
}
switch
문
switch
문은 하나의 정수 표현식 값에 따라 여러 경로 중 하나를 선택하여 실행하는 다중 선택문이다. if-else if
구조보다 코드가 간결해질 수 있다.
-
switch (expression)
:expression
은 반드시 정수형으로 평가되어야 한다. -
case value:
:expression
의 결과값과value
(정수 상수)가 일치하면 해당case
의 문장부터 실행된다. -
break
:switch
블록을 즉시 빠져나간다.break
가 없으면 일치하는case
이후의 모든case
문장들이 순차적으로 실행된다(fall-through). 이를 이용해 여러case
에 대해 동일한 코드를 실행시킬 수 있다.
-
default
: 어떤case
와도 일치하지 않을 때 실행된다.
윤년 계산 예시: switch
문과 if
문을 활용하여 특정 년도의 월별 마지막 날을 계산할 수 있다. 2월의 경우, 윤년을 판별하는 로직이 필요하다. 윤년의 조건은 다음과 같다:
- 4로 나누어 떨어지면서 100으로 나누어 떨어지지 않는 해
- 또는 400으로 나누어 떨어지는 해
((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)