본문으로 건너뛰기

비트와 여러 연산자

조건 연산자 (Conditional Operator)

C 언어에서 유일하게 3개의 **Operand(피연산자)**를 갖는 삼항 연산자이다. 이 연산자는 ?: 두 개의 기호로 구성된다.

문법: exp1 ? exp2 : exp3

  • exp1이 참(0이 아닌 값)으로 평가되면, 전체 연산식의 결과는 exp2의 값이 된다.
  • exp1이 거짓(0)으로 평가되면, 전체 연산식의 결과는 exp3의 값이 된다.

예를 들어, max = (a > b) ? a : b; 문장은 ab보다 크면 maxa를, 그렇지 않으면 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 연산은 a2^b를 곱하는 효과와 같다.
  • 오른쪽 이동 (>>): 비트들을 오른쪽으로 이동시키고, 오른쪽 경계를 벗어나는 비트는 버려진다. 왼쪽의 빈자리는 원래 숫자의 부호 비트(최상위 비트)로 채워진다. 만약 피연산자가 양수라면 a >> b 연산은 a2^b로 나누는 효과와 같다.

비트 마스크 (Bit Mask)

**Bit Mask(비트 마스크)**는 특정 비트들만 선택하거나 변경하기 위해 사용하는 상수나 변수이다.

  • 특정 비트 값 확인: 확인하려는 비트 위치만 1이고 나머지는 0인 마스크를 만들어 & 연산을 수행한다. 예를 들어, 변수 a의 n번째 비트를 확인하는 일반식은 (a & (1 << (n-1)))이다.
  • 특정 비트 값 변경:
    • 비트를 1로 설정: | 연산을 사용한다.
    • 비트를 0으로 설정: 해당 비트만 1인 마스크를 ~로 반전시킨 후 & 연산을 사용한다.
    • 비트 반전(toggle): ^ 연산을 사용한다.

기타 연산자

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 += yx = x + y와 동일한 의미를 가진다.

콤마 연산자 (Comma Operator)

콤마 연산자는 우선순위가 가장 낮다. 왼쪽에서 오른쪽으로 연산을 수행하며, 전체 연산식의 결과값은 가장 마지막에 수행된 연산의 결과가 된다.

  • x = 3+4, 5-10;: 대입 연산자가 콤마보다 우선순위가 높아 x = 7이 먼저 수행되고, 5-10은 의미 없는 구문이 된다.

  • x = (3+4, 5-10);: 괄호 안의 콤마 연산자가 먼저 수행된다. 3+4가 수행된 후 5-10이 수행되고, 마지막 결과인 -5x에 대입된다.

연산자 우선순위

C 언어의 연산자는 정해진 **Operator Precedence(연산자 우선순위)**에 따라 평가된다. 일반적으로 우선순위는 다음과 같다:

  1. 괄호 (), 배열 [], 구조체 . ->
  2. 단항 연산자 (++, --, !, ~, sizeof)
  3. 산술 연산자 (*, /, %, +, -)
  4. 이동 연산자 (<<, >>)
  5. 관계 연산자 (<, >, <=, >=)
  6. 등가 연산자 (==, !=)
  7. 비트 논리 연산자 (&, ^, |)
  8. 논리 연산자 (&&, ||)
  9. 조건 연산자 (?:)
  10. 대입 연산자 (=, +=, -=, 등)
  11. 콤마 연산자 (,)

조건문

조건문은 특정 조건을 만족할 때만 해당하는 코드를 실행하도록 제어하는 문장이다.

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");
}

중첩된 ifelse 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)