비트 연산자와 시프트 연산자로 비트 단위 연산하기
비트 연산자(&, |, ^, ~)와 시프트 연산자(<<, >>)는 이진수 비트 단위로 연산을 수행합니다. 변수 값을 비트 단위로 연산하는 비트 연산자와 시프트 연산자의 사용법을 알아봅시다.
> // 비트 연산자: & (비트단위 AND), | (비트단위 OR), ^ (비트단위 XOR), ~ (비트단위 NOT)
> // 시프트 연산자: << (왼쪽 시프트), >> (오른쪽 시프트), >>> (부호없는 오른쪽 시프트)
책읽기: 비트 연산자와 시프트 연산자로 비트 단위 연산하기 강의 소개
비트 연산자와 시프트 연산자의 종류
비트 연산자와 시프트 연산자는 2진수 비트 단위로 연산을 수행하는데 사용합니다. 우선 비트 연산자와 시프트 연산자의 7가지 종류를 표로 간단히 미리 살펴본 후 진행하겠습니다.
[표] 비트 연산자와 시프트 연산자의 종류
연산자 | 별칭 | 설명 |
---|---|---|
& | 비트단위 AND | 비트 값이 둘 다 1일 때에만 1, 그렇지 않으면 0 |
| | 비트단위 OR | 비트 값이 하나라도 1이면 1, 그렇지 않으면 0 |
^ | 비트단위 XOR | 비트 값이 서로 다를 때에만 1, 그렇지 않으면 0 |
~ | 비트단위 NOT | 비트 값이 1이면 0, 0이면 1 |
<< | 왼쪽 시프트 | 비트 값을 지정된 수만큼 왼쪽으로 이동 |
>> | 오른쪽 시프트 | 비트 값을 지정된 수만큼 오른쪽으로 이동 |
>>> | 부호없는 오른쪽 시프트 | 비트 값을 지정된 수만큼 오른쪽으로 이동하되 왼쪽을 0으로 채움 |
비트 연산자
비트 연산자(Bit Operator)는 정수형 데이터의 값을 이진수의 비트 단위로 연산을 수행하고자할 때 사용됩니다. 비트 연산자는 다음과 같이 4개의 기호를 사용합니다. 좀 더 구분을 짓기 위해서 영문 단어를 추가했습니다.
- &
- 논리곱(AND, Both)
- |
- 논리합(OR, Either)
- ^
- 배타적 논리합(XOR; Exclusive OR, Different)
- !
- NOT(Negation, Invert)
비트 연산자 AND, OR, XOR 간단 소개 동영상
Windows 계산기를 사용하여 이진수 비트 연산자 4개에 대한 실행 결과 살펴보기
Windows OS에 내장된 계산기를 사용하면 표준, 공학용, 프로그래머용 등의 여러 가지 환경을 사용할 수 있습니다.
그림: 계산기
비트 AND 연산자(&
) 사용하기
본격적으로 비트 연산자를 사용하도록 하겠습니다. 먼저, 비트 AND 연산자인 & 연산자를 사용해 보겠습니다. 다음 코드를 주석을 제외하고 작성 후 실행해보세요.
그림: 계산기로 AND 연산 수행하기
코드: BitAnd.cs
> // & 연산자: 비트 AND 연산자(둘 다 1일때만 1)
> byte x = 0b1010; // 10
> byte y = 0b1100; // 12
>
> // x를 이진수로 표현 -> 십진수로 표현
> Console.WriteLine($" {Convert.ToString(x, 2)} -> {x}");
1010 -> 10
>
> // y를 이진수로 표현 -> 십진수로 표현
> Console.WriteLine($"& {Convert.ToString(y, 2)} -> {y}");
& 1100 -> 12
>
> // x AND y를 이진수로 표현 -> 십진수로 2칸 잡고 표현
> Console.WriteLine($" {Convert.ToString(x & y, 2)} -> {x & y, 2}");
1000 -> 8
비트 AND
연산자인 &
연산자처럼 항을 2개 갖는 2항 연산자는 앞뒤로 공백을 두면 가독성이 좋아집니다. 즉, x%y
보다는 x % y
형태를 추천합니다.
비트 OR 연산자(|
) 사용하기
이번에는 비트 OR
연산자인 |
연산자를 사용해 보겠습니다. |
연산자는 키보드의 파이프 기호(버티컬 바)를 사용합니다.
그림: 계산기로 OR 연산 수행하기
코드: BitOr.cs
> // | 연산자: 비트 OR 연산자(하나라도 1이면 1)
> using static System.Console; // System.Console 줄여서 사용
>
> byte x = 0b1010; // 10
> byte y = 0b1100; // 12
>
> // x를 이진수로 표현 -> 십진수로 표현
> WriteLine($" {Convert.ToString(x, 2)} -> {x}");
1010 -> 10
>
> // y를 이진수로 표현 -> 십진수로 표현
> WriteLine($"| {Convert.ToString(y, 2)} -> {y}");
| 1100 -> 12
>
> // x OR y를 이진수로 표현 -> 십진수로 표현
> WriteLine($" {Convert.ToString(x | y, 2)} -> {x | y,2}");
1110 -> 14
나중에 프로그래머로 일을 하다 보면 이진수 처리가 중요한 분야가 있을 수 있습니다. 지금은 '이런 연산자를 사용하면 이렇게 나오는구나' 정도로 가볍게 읽고 넘어갑니다.
비트 XOR 연산자(^
) 사용하기
비트 XOR
연산자 ^
는 두 비트의 값이 서로 다를 때 1
이 되는 연산자입니다. 즉, 1 ^ 0
과 0 ^ 1
일 때만 1
이고, 나머지 경우에는 0
이 됩니다.
XOR
은 "엑스오어"라고 읽으며, ^
기호는 흔히 "삿갓"이라고도 하지만, 정확한 명칭은 "캐럿(caret)"입니다.
그림: 계산기로 XOR 연산 수행하기
코드: BitXor.cs
> // ^ 연산자: 비트 XOR 연산자(서로 다르면 1)
> using static System.Console;
>
> byte x = 0b_1010; // 10
> byte y = 0b_1100; // 12
>
> // x를 이진수로 표현 -> 십진수로 표현
> WriteLine($" {Convert.ToString(x, 2)} -> {x}");
1010 -> 10
>
> // y를 이진수로 표현 -> 십진수로 표현
> WriteLine($"^ {Convert.ToString(y, 2)} -> {y}");
^ 1100 -> 12
>
> // x XOR y를 이진수로 표현 -> 십진수로 표현
> WriteLine($" {Convert.ToString(x ^ y, 2).PadLeft(4, '0')} -> {x ^ y,2}");
0110 -> 6
^
연산자를 포함한 몇몇 비트 및 시프트 연산자는 이번 예제 이외에는 다루지 않습니다. 그러므로 현재 예제는 가볍게 작성 후 실행해보세요.
비트 연산자는 하드웨어 제어 같은 경우가 아니면 자주 쓰이지 않습니다. 여기서는 비트 연산자의 사용법만 살펴보면 충분합니다.
비트 NOT 연산자(~
) 사용하기
비트 NOT
연산자인 ~
연산자는 물결(틸드) 기호를 사용합니다. ~
연산자는 비트 값이 1
이면 0
으로 0
이면 1
로 바꿉니다. 이렇게 비트가 바뀌는 것이 '비트 반전'입니다.
그림: 계산기로 비트 반전
코드: BitNot.cs
> // ~ 연산자: 비트 NOT 연산자(1 <-> 0, 비트 반전)
> using static System.Console;
>
> byte x = 0b_0000_1010; // 10
>
> // x를 8자리 이진수로 표현 -> 십진수로 3자리 잡고 표현
> WriteLine($"~ {Convert.ToString(x, 2).PadLeft(8, '0')} -> {x, 3}");
~ 00001010 -> 10
>
> // NOT x를 8자리 이진수로 표현 -> 십진수로 3자리 잡고 표현
> WriteLine($" {Convert.ToString((byte)~x, 2).PadLeft(8, '0')} -> {~x, 3}");
11110101 -> -11
음수를 이진수로 표현할 때는 2의 보수법을 사용합니다. C#에서는 자동으로 이진수를 양수 또는 음수로 해석하여 출력합니다.
비트 연산자 4가지 모두 사용해보기
이번에는 비트 연산자 4개를 모아서 사용해 보겠습니다. 다음 내용을 입력한 후 실행해 보세요.
코드: BitwiseOperator.cs
// 비트 연산자: &, |, ~, ^
using System;
class BitwiseOperator
{
static void Main()
{
var x = Convert.ToInt32("1010", 2); // 10
var y = Convert.ToInt32("0110", 2); // 6
var and = x & y;
Console.WriteLine($"{and} : {Convert.ToString(and, 2)}"); // 2, 0010
var or = x | y;
Console.WriteLine($"{or} : {Convert.ToString(or, 2)}"); // 14, 1110
var xor = x ^ y;
Console.WriteLine($"{xor} : {Convert.ToString(xor, 2)}"); // 12, 1100
var not = ~x; // 2의 보수법에 의해서 1010 + 1 그리고 부호를 -로 -1011 => -11
Console.WriteLine($"{not} : {Convert.ToString(not, 2)}"); // -11, ~~~~0101
}
}
2 : 10
14 : 1110
12 : 1100
-11 : 11111111111111111111111111110101
이진수 1010
과 0110
에 대해서 &
, |
, ^
연산자를 사용한 결과와 1010
에 ~
연산자를 붙여 비트를 반전시키는 연산의 사용 결과가 나옵니다.
시프트 연산자
시프트 연산자(Shift Operator)는 정수 데이터가 담겨 있는 메모리의 비트를 왼쪽(<<
) 또는 오른쪽(>>
, >>>
)으로 지정한 비트만큼 이동시켜주는 기능을 제공합니다.
시프트 연산자를 사용하면 비트의 자리를 다음과 같이 이동할 수 있습니다.
x << y
:x
를y
만큼 왼쪽으로 이동x >> y
:x
를y
만큼 오른쪽으로 이동x >>> y
:x
를y
만큼 부호없이 왼쪽을 0으로 채우며 오른쪽으로 이동
예를 들어, 정수형 데이터인 2
를 이진수로 표현하면 0010
입니다. 왼쪽(<<
) 시프트 연산자를 사용하여 한 칸 이동하면 0100
이 됩니다. 이진수 0010
을 오른쪽(>>
) 시프트 연산자를 사용하여 한 칸 이동하면 0001
이 됩니다.
비트 연산자의 사용 예를 표로 정리하면 다음과 같습니다.
연산자 | 사용 예 | 설명 |
---|---|---|
<< | 변수 << 비트값; | 비트값 만큼 왼쪽으로 비트 이동 결괏값이 변수의 값 * 2의 비트값 제곱 == 비트당 2배 변수의 값 곱하기 2의 거듭제곱 |
>> | 변수 >> 비트값; | 비트값 만큼 오른쪽으로 비트 이동 결괏값이 변수의 값 / 2의 비트값 제곱 == 비트당 1/2배 변수의 값 나누기 2의 거듭제곱 |
그림: 계산기로 2 << 2
실행하기
그림: 계산기로 40 >> 2
실행하기
시프트 연산자에 대한 내용을 그림으로 표현하면 다음과 같습니다.
그림: 시프트 연산자
정수 2
의 이진수인 0010
을 왼쪽으로 2
칸 이동하면 1000
이 되어 정수 8
이 됩니다.
정수 40
의 이진수인 0101000
를 오른쪽으로 2
칸 이동하면 0001010
이 되어 정수 10
이 됩니다.
시프트 연산자 사용하기
코드로 시프트 연산자를 사용해 보도록 하겠습니다.
***코드: ShiftOperatorDemo.cs ***
> int number = 2; // 0010
>
> Console.WriteLine(number << 1); // 0010 -> 0100 : 4
4
>
> Console.WriteLine(number >> 1); // 0010 -> 0001 : 1
1
이진수 0010
을 왼쪽으로 비트를 한 칸 이동하면 0100
이 되고 이진수 0010
을 오른쪽으로 비트를 한 칸 이동하면 0001
이 됩니다. 시프트 연산자는 내부적으로는 이진수로 계산이 되지만 정수형 데이터이기에 출력할 때에는 그대로 십진수로 표현됩니다.
부호 없는 오른쪽 시프트 연산자(>>>
) 사용하기
C#에서는 오른쪽 시프트 연산자로 산술 오른쪽 시프트 연산자(>>
)와 부호 없는 오른쪽 시프트 연산자(>>>
)의 두 가지를 사용할 수 있습니다.
C# 11에서 도입된 >>>
연산자는 부호 없는 오른쪽 시프트 연산자로, 왼쪽 피연산자를 오른쪽 피연산자가 지정한 비트 수만큼 오른쪽으로 이동시킵니다. 이때, >>>
연산자는 왼쪽 피연산자의 유형과 관계없이 상위 비트 위치를 항상 0
으로 설정합니다.
다음 코드는 음수 값을 오른쪽으로 시프트하는 부호 없는 오른쪽 시프트 연산자의 사용 예제를 보여줍니다.
코드: UnsignedRightShiftDemo.cs
using static System.Console;
class UnsignedRightShiftDemo
{
static void Main()
{
int x = -4;
WriteLine($"{x,11}, {Convert.ToString(x, 2).PadLeft(32, '0'),32}");
int y = x >> 1;
WriteLine($"{y,11}, {Convert.ToString(y, 2).PadLeft(32, '0'),32}");
int z = x >>> 1;
WriteLine($"{z,11}, {Convert.ToString(z, 2).PadLeft(32, '0'),32}");
}
}
-4, 11111111111111111111111111111100
-2, 11111111111111111111111111111110
2147483646, 01111111111111111111111111111110
위 코드에서 x
의 초기값은 -4
이며, 이를 이진수로 나타내면 11111111 11111111 11111111 11111100
입니다. 먼저, x
에 산술 오른쪽 시프트 연산자(>>
)를 적용하면 최상위 비트(부호 비트)를 유지한 채 한 비트씩 오른쪽으로 이동합니다. 따라서 결과는 11111111 11111111 11111111 11111110
이 되며, 이는 10진수로 -2
에 해당합니다.
반면, x
에 부호 없는 오른쪽 시프트 연산자(>>>
)를 적용하면, 부호와 관계없이 왼쪽의 빈 비트를 항상 0
으로 채우면서 한 비트씩 이동합니다. 따라서 결과는 01111111 11111111 11111111 11111110
이 되며, 이는 10진수로 2147483646
에 해당합니다.
이처럼 산술 오른쪽 시프트(>>
)는 최상위 비트를 유지하여 음수를 그대로 유지하는 반면, 부호 없는 오른쪽 시프트(>>>
)는 상위 빈 비트를 0
으로 설정하기 때문에 음수 값이 양수로 변환될 수 있습니다.
비트 연산자와 시프트 연산자를 할당 연산자와 함께 사용하기
비트 연산자와 시프트 연산자도 할당 연산자와 함께 사용할 수 있습니다. 사용 방법은 일반적인 할당 연산자와 동일합니다.
A &= B;
A |= B;
A ^= B;
A <<= B;
A >>= B;
이번에는 할당 연산자와 함께 비트 연산자, 시프트 연산자를 사용해 보겠습니다.
코드: BitwiseAssignment.cs
> byte num1 = 4; // 4: 0000_0100
> num1 &= 5; // 5(0101) & 4(0100) => 4(0000_0100)
> Console.WriteLine(num1); // 4
4
>
> byte num2 = 4; // 4: 0000_0100
> num2 |= 1; // 1(0001) & 4(0100) => 5(0000_0101)
> Console.WriteLine(num2); // 5
5
>
> byte num3 = 4; // 4: 0000_0100
> num3 ^= 2; // 2(0010) & 4(0100) => 6(0000_0110)
> Console.WriteLine(num3); // 6
6
>
> byte num4 = 4; // 4: 0000_0100
> num4 <<= 1; // 4(0100) << 1 => 8(0000_1000)
> Console.WriteLine(num4); // 8
8
>
> byte num5 = 4; // 4: 0000_0100
> num5 >>= 1; // 4(0100) >> 1 => 2(0000_0010)
> Console.WriteLine(num5); // 2
2
결과는 2진수 비트 연산 후 그 결괏값을 다시 변수에 할당한 내용이 출력됩니다.
비트 연산자와 시프트 연산자는 C언어와 같은 프로그래밍 언어로 성능이 낮은 장치에 대한 프로그래밍할 때 많이 사용됩니다. 다만, C#에서 응용 프로그램을 제작할 때에는 자주 사용되지 않습니다. 이번 강의의 예제의 내용 정도만 이해하고 다음으로 넘어가도 충분합니다.
기타 연산자
앞에서 살펴본 연산자 외에도 여러 연산자가 있습니다. 그중 조건 연산자와 나열 연산자, sizeof
연산자를 살펴봅시다.
조건 연산자
> // 조건 연산자(3항 연산자): "조건식 ? 조건식이참일때의값 : 조건식이거짓일때의값"
물음표와 콜론 기호를 함께 사용하는 "? :"
형태의 모양을 갖는 조건 연산자(Conditional Operator)도 있습니다. 조건연산자는 조건에 따라서 참(true)일 때와 거짓(false)일 때의 결과를 다르게 반환하고자 할 때 사용됩니다. 조건 연산자는 항이 3개여서 3항 연산자(Ternary Operator)라고도 합니다. 3항 연산자는 뒤에서 다룰 if ~ else
문의 축약형이기도 합니다.
> (5 > 3) ? "TRUE" : "FALSE"
"TRUE"
3항 연산자인 ?:
연산자는 항이 3개가 있는 연산자로 다음과 같이 조건을 처리합니다.
조건식 ? 식1 : 식2;
조건식이 참이면 식1이 실행되고 조건식이 거짓이면 식2가 실행됩니다.
3항 연산자의 결괏값이 특정 값을 반환하기에 다음과 같이 표현하기도 합니다.
조건식 ? 값1 : 값2;
?:
연산자 보충 설명
다음 예제와 같이, 3개로 구성된 조건 연산자라고도 하는 조건 연산자 ?:
은 부울 식을 계산하고 부울 식이 true
또는 false
로 계산되는지에 따라 두 식 중 하나의 결과를 반환합니다.
(tempInCelsius < 20.0) ? "Cold." : "Perfect!";
위의 예제에서 볼 수 있듯이 조건 연산자의 구문은 다음과 같습니다.
condition ? consequent : alternative
condition
식은 true
또는 false
로 계산되어야 합니다. condition
이 true
로 계산되면 consequent
식이 계산되고 해당 결과가 연산 결과가 됩니다. condition
이 false
로 계산되면 alternative
식이 계산되고 해당 결과가 연산 결과가 됩니다. consequent
또는 alternative
만 계산됩니다.
조건부 연산자는 오른쪽 결합성입니다. 즉, 다음 형식의 식을 가정해 보세요.
a ? b : c ? d : e
이 식은 다음과 같이 계산됩니다.
a ? b : (c ? d : e)
TIP
다음과 같은 니모닉 디바이스(mnemonic device)를 사용하여 조건부 연산자의 평가 방식을 기억할 수 있습니다.
is this condition true ? yes : no
조건 연산자 사용하기
3항 연산자인 조건 연산자를 사용해보겠습니다.
코드: ConditionalOperator.cs
> //[?] 3항 연산자(조건 연산자) 사용하기
> int number = 3;
>
> // number가 짝수면 result 변수에 "짝수" 담고 그렇지 않으면 "홀수" 담기
> string result = (number % 2 == 0) ? "짝수" : "홀수";
>
> Console.WriteLine($"{number}은(는) {result}입니다.");
3은(는) 홀수입니다.
num
변수에 3
을 넣어 놓은 후 (num % 2 == 0)
을 물어보면 거짓(false
)이 됩니다. 물음표(?
) 기호 앞의 식이 false
이기에 '홀수'가 result
변수에 담깁니다. 즉, 조건식이 참이면 '짝수'를 반환, 그렇지 않으면 '홀수'를 반환합니다.
참고로, 조건 연산자, 즉 3항 연산자는 앞으로 배울 제어문의 if
문으로 대체할 수 있습니다.
조건 연산자를 사용하여 최댓값 정하기
이번에는 조건 연산자를 사용하여 최댓값을 우리가 원하는 값으로 정하는 방법을 알아보겠습니다.
코드: OperatorMaxSize.cs
> //[?] 들어오는 값이 20 이상이면 20으로 초기화, 20 미만이면 해당 값으로 초기화
> const int maxSize = 20; // 최댓값을 20으로 정함
> int pageSize = 0;
>
> pageSize = 10;
> pageSize = (pageSize > maxSize) ? maxSize : pageSize; // 10
> pageSize
10
>
> pageSize = 50;
> pageSize = (pageSize > maxSize) ? maxSize : pageSize; // 20
> pageSize
20
pageSize
변수에 들어오는 값이 20
보다 작으면 pageSize
값 그대로 출력하고, 20
이상이면 20
으로 고정하는 기능을 구현해 보았습니다.
조건 연산자를 사용하여 문자 비교하기
이번에는 조건 연산자를 사용하여 문자 크기를 비교해 보겠습니다.
코드: TernaryOperator.cs
> string result = "";
>
> // 'A'는 'B'보다 작으므로 참이므로 앞에 문자열이 result 변수에 저장
> result = ('A' < 'B') ? "'A'는 'B'보다 작습니다." : "A B C 순서로 커집니다.";
> result
"'A'는 'B'보다 작습니다."
>
> // 'Z'는 'a'보다 작으므로 참이므로 앞에 문자열이 result 변수에 저장
> result = ('Z' < 'a') ? "'Z'는 'a'보다 작습니다." : "대문자보다 소문자가 더 큽니다.";
> result
"'Z'는 'a'보다 작습니다."
프로그래밍 언어에서는 A, B, C, …, Z, a, b, c, …, z
순서로 크기가 정해져 있습니다. 이러한 크기를 조건 연산자의 조건식에 두고 크기를 비교해 보았습니다.
조건(3항) 연산자로 절댓값 구하기
조건 연산자인 3항 연산자를 사용하면 다음 코드처럼 정수의 절댓값을 편하게 구할 수 있습니다.
코드: AbsoluteValue.cs
> var num = -21; // 음수 값을 저장
> var abs = (num < 0) ? -num : num; // 3항 연산자로 음수만 부호 변환
> Console.WriteLine($"{num}의 절댓값: {abs}");
-21의 절댓값: 21
나열(콤마) 연산자
이미 변수 선언할 때 다루어 보았지만, 콤마를 구분자로 하여 하나의 문장에 여러 개의 변수 선언문을 지정할 때 사용합니다. 이러한 콤마 연산자(Comma Operator)를 나열 연산자라고도 합니다. 나열 연산자는 다음과 같이 사용됩니다.
int a = 10, b = 20, c = 30;
위와 같이 콤마로 3개의 할당문이 지정되면, a, b, c
변수 모두 int
형 변수로 선언됩니다.
IMPORTANT
콤마 연산자는 코드가 복잡해질 수 있기에 가능하면 사용하지 않습니다.
sizeof
연산자로 데이터 타입의 크기 구하기
sizeof
연산자는 단항 연산자로서 데이터 타입 자체의 크기를 구하는데 사용됩니다. sizeof(int)
형태로 사용되며 int
의 데이터 타입 크기인 4
가 값으로 나옵니다. 참고로, sizeof
연산자의 결괏값이 플랫폼마다 다르게 나올 수 있습니다.
코드: SizeOf.cs
> //[?] sizeof 연산자로 데이터 형식의 크기 구하기
> Console.WriteLine("sizeof(데이터 형식)");
sizeof(데이터 형식)
> Console.WriteLine($" char 형식: {sizeof( char)} byte");
char 형식: 2 byte
> Console.WriteLine($" int 형식: {sizeof( int)} byte");
int 형식: 4 byte
> Console.WriteLine($" long 형식: {sizeof( long)} byte");
long 형식: 8 byte
> Console.WriteLine($" float 형식: {sizeof( float)} byte");
float 형식: 4 byte
> Console.WriteLine($"double 형식: {sizeof(double)} byte");
double 형식: 8 byte
sizeof
연산자는 다른 연산자와 달리 sizeof()
형태로 괄호로 묶어주는 형태를 가집니다. C#의 기본 제공 형식의 크기는 예를 들어 double
이라면 sizeof(double)
형태로 구할 수 있습니다.
연산자 우선 순위
여러 개의 연산자를 사용할 때에는 연산자의 우선순위(Precedence)에 따라서 계산됩니다. 예를 들어 산술 연산자에서 +
보다 *
가 더 우선순위가 높습니다. 괄호 연산자인 ()
연산자를 사용하면 우선순위를 변경할 수도 있습니다.
표: 우선순위가 적용된 산술 연산 구문
다음은 C#의 주요 연산자 우선순위입니다.
표: 연산자 우선순위
연산자 우선순위는 따로 외울 필요 없이 괄호 연산자만 잘 사용해도 무방합니다. 나머지는 자연스레 프로그래밍을 배우면서 알아 가면 됩니다.
다음 코드는 참고용으로 살펴보세요.
코드: OperatorPrecedence.cs
> 3 + 4 * 2
11
> (3 + 4) * 2
14
> 10 / 5 * 2 + 1
5
> 15 / (5 * (2 + 1))
1
장 요약
3항 연산자인 조건 연산자는 조건식이 참일 때와 거짓일 때에 따라 서로 다른 값을 받고 싶을 때 사용합니다. 이 연산자는 다음 강의에서 배울 if 문으로 대체가 가능합니다. 그 외에 콤마 연산자와 연산자 우선순위도 학습했습니다. 연산자는 이 정도로 정리하고 다음 강의부터는 제어문을 학습하겠습니다
정보처리산업기사 실기 시험 기출 문제 - 비트 및 논리 연산 출력
문제
다음 C# 프로그램이 실행되었을 때의 동작을 설명하고, 출력 결과를 예측하시오.
소스 코드 파일명: BitwiseLogicalOperations.cs
using System;
class BitwiseLogicalOperations
{
static void Main()
{
int x = 1;
Console.WriteLine(!(x > 0));
Console.WriteLine(x > 0 || x < 4);
Console.WriteLine(x << 2);
Console.WriteLine(x & 2);
Console.WriteLine(x % 3);
}
}
입력 예시
이 프로그램은 입력을 받지 않습니다.
출력 예시
False
True
4
0
1
해설
이 프로그램은 변수 x
의 값에 대한 여러 가지 비트 연산 및 논리 연산을 수행하고 그 결과를 출력합니다.
int x = 1;
는 정수 변수x
를 선언하고 1로 초기화합니다.Console.WriteLine(!(x > 0));
는x > 0
의 조건이 참이므로,!
연산자를 사용하여 그 결과를 반전시킵니다. 따라서False
가 출력됩니다.Console.WriteLine(x > 0 || x < 4);
는x > 0
또는x < 4
의 조건 중 하나라도 참이면True
를 반환합니다. 두 조건 모두 참이므로,True
가 출력됩니다.Console.WriteLine(x << 2);
는x
의 값을 왼쪽으로 2비트 이동시킵니다.x
의 값인 1을 2진수로01
로 표현할 때, 왼쪽으로 2비트 이동시키면100
이 되어, 10진수로 4가 됩니다. 따라서4
가 출력됩니다.Console.WriteLine(x & 2);
는x
의 값과 2를 비트 AND 연산합니다.x
의 2진수 값01
과 2의 2진수 값10
을 AND 연산하면00
이 되어, 10진수로 0이 됩니다. 따라서0
이 출력됩니다.Console.WriteLine(x % 3);
는x
를 3으로 나눈 나머지를 출력합니다. 1을 3으로 나눈 나머지는 1이므로,1
이 출력됩니다.
이 프로그램은 기본적인 비트 연산과 논리 연산을 통해 다양한 결과를 출력하며, 조건 연산자와 비트 이동 연산자 등의 사용 방법을 이해하는 데 도움을 줍니다. C#에서는 논리 연산 결과를 대문자 True
와 False
로 출력하는 것을 제외하고는 Java와 매우 유사한 동작을 합니다.
정보처리산업기사 실기 시험 기출 문제 - 복합 비트 연산 및 조건식
문제
다음 C# 프로그램이 실행되었을 때의 동작을 설명하고, 출력 결과를 예측하시오.
소스 코드 파일명: ComplexBitwiseLogicalOperations.cs
using System;
class ComplexBitwiseLogicalOperations
{
static void Main()
{
int a = 5, b = 9, c;
c = b % 5 < 5 ? 1 : 0;
c = c | (c << 3);
c = (a < 5 || c >= 10) ? (c - a) : (c + a);
Console.WriteLine(c);
}
}
입력 예시
이 프로그램은 입력을 받지 않습니다.
출력 예시
14
해설
이 프로그램은 변수 a
, b
, c
에 대한 복합 비트 연산 및 조건식을 이용하여 최종적으로 c
의 값을 결정하고 출력합니다.
int a = 5, b = 9, c;
는 정수 변수a
,b
,c
를 선언하고 초기화합니다.c
는 먼저b % 5 < 5
조건을 평가하여1
로 설정됩니다. 이는b
의 나머지가 5보다 작을 경우1
, 그렇지 않으면0
을c
에 할당하는 조건 연산자입니다.- 그 다음,
c
는 자기 자신과 자기 자신을 3비트 왼쪽으로 이동한 값과의 비트 OR 연산 결과로 업데이트됩니다. 이 연산은c
에9
를 할당합니다. - 마지막으로,
(a < 5 || c >= 10)
조건을 평가한 후, 해당 조건이 거짓이므로(c + a)
연산을 수행하여c
는14
가 됩니다. Console.WriteLine(c);
는 수정된c
의 값인14
를 출력합니다.
이 프로그램은 복합 비트 연산과 조건식을 사용하여 변수의 값을 조작하는 과정을 보여주며, 이러한 연산들이 어떻게 결합되어 최종 결과를 도출하는지를 이해하는 데 도움을 줍니다. C#에서는 이러한 비트 및 조건 연산을 통해 복잡한 논리를 간결하게 표현할 수 있습니다.
1.1 퀴즈
(1) 4 & 1
의 연산 결과로 올바른 것을 고르세요.
a. 0000 0000 (0)
b. 0000 0010 (2)
c. 0000 0100 (4)
d. 0000 0110 (6)
e. 0000 1000 (8)
정답: a
비트 AND(
&
) 연산자는 두 비트가 모두1
일 때만1
이 됩니다.
0100 (4)
0001 (1)
&
0000 (0)
(2) 4 | 1
의 연산 결과로 올바른 것을 고르세요.
a. 0000 0001 (1)
b. 0000 0010 (2)
c. 0000 0011 (3)
d. 0000 0100 (4)
e. 0000 0101 (5)
정답: e
비트 OR(
|
) 연산자는 두 비트 중 하나라도1
이면1
이 됩니다.
0100 (4)
0001 (1)
|
0101 (5)
(3) 5 ^ 1
의 연산 결과로 올바른 것을 고르세요.
a. 0000 0001 (1)
b. 0000 0010 (2)
c. 0000 0011 (3)
d. 0000 0100 (4)
e. 0000 0101 (5)
정답: d
비트 XOR(
^
) 연산자는 두 비트가 다를 때1
이 됩니다.
0101 (5)
0001 (1)
^
0100 (4)
(4) 2 << 2 >> 1
의 연산 결과로 올바른 것을 고르세요.
a. 0000 0001 (1)
b. 0000 0010 (2)
c. 0000 0011 (3)
d. 0000 0100 (4)
e. 0000 0101 (5)
정답: d
- 왼쪽 시프트(
<<
)는 비트를 왼쪽으로 이동- 오른쪽 시프트(
>>
)는 비트를 오른쪽으로 이동
0010 (2)
<< 2
1000 (8)
>> 1
0100 (4)
1.2 연습문제: 시프트 연산자 사용하기
다음 소스 코드를 완성하여 **4
**가 출력되도록 하세요.
코드
using System;
class ShiftPractice
{
static void Main()
{
Console.WriteLine(8 >> 3 << 2); // 4
}
}
실행 결과
4
정답
2
해설
8 (0000 1000)
을 오른쪽으로 3번 이동하면1 (0000 0001)
이 됩니다.- 이를 다시 왼쪽으로 2번 이동하면
4 (0000 0100)
이 됩니다.
1.1 퀴즈
(1) 다음 코드 실행 결과, 변수 two
의 값으로 올바른 것을 고르세요.
int one = 1;
int two = 2;
two = (one > 1) ? 1111 : 2222;
a. 1
b. 2
c. 1111
d. 2222
정답: d
변수
one
의 값이1
이므로(1 > 1)
조건식은 거짓이 됩니다. 따라서two
변수에는 2222가 저장됩니다.
(2) 다음 코드 실행 결과, 변수 result
의 값으로 올바른 것을 고르세요.
int number = 1;
int result = 0;
result = 8 >> 2 * number++ - (3 % 2);
a. 1
b. 2
c. 4
d. 8
정답: c
연산자 우선순위에 따라 아래 순서대로 계산됩니다.
(3 % 2)
→1
2 * number++
→2
(number
는 이후2
가 됨)2 - 1
→1
8 >> 1
→4
(비트 연산8
을 오른쪽으로1
비트 이동)result = 4
따라서 result
변수에는 4
가 저장됩니다.
1.2 연습문제: 조건 연산자 사용하기
다음 소스 코드를 완성하여 **"점수: 59, 결과: 불합격"**이 출력되도록 하세요.
코드
using System;
class TernaryPractice
{
static void Main()
{
int score = 59;
string result = "";
result = (score >= 60) ? "합격" : "불합격";
Console.WriteLine($"점수: {score}, 결과: {result}");
}
}
실행 결과
점수: 59, 결과: 불합격
정답
? :
또는
>= ? :
또는
== ? :
해설
조건 연산자(? :
)는 3항 연산자라고도 하며,
(조건식) ? 값1 : 값2
형태로 사용됩니다.
score >= 60
조건식이 참이면"합격"
을 반환하고,- 거짓이면
"불합격"
을 반환합니다.
주어진 값이 59
이며, "불합격"
이 출력되어야 하므로 조건식이 거짓이 되는 연산자 (>
, >=
, ==
등)를 사용할 수 있습니다.