본문 바로가기
공부/C#

이것이 C#이다 Chapter 04 데이터를 가공하는 연산자

by bokob 2024. 2. 23.

4.1 C#에서 제공하는 연산자 둘러보기

분류 연산자
산술 연산자 +, -, *, /, %
증가/감소 연산자 ++, --
관계 연산자 <, >, ==, !=, <=, >=
논리 연산자 &&, ||, !
조건 연산자 ?:
null 조건부 연산자 ?., ?[]
비트 연산자 <<, >>, &, |, ^, ~
할당 연산자 =, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
null 병합 연산자 ??

 

4.2 산술 연산자

산술 연산자는 두 개의 피연산자가 필요하다. 이를 이항 연산자(Binary Operator)라고 한다.

산술 연산자의 우선순위는 수학에서의 사직연산 우선순위와 같다.

연산자 설명 지원 타입
+ 양쪽 피연산자를 더한다. 모든 수치 데이터 타입
- 왼쪽 피연산자에서 오른쪽 피연산자를 뺀다. 모든 수치 데이터 타입
* 양쪽 피연산자를 곱한다. 모든 수치 데이터 타입
/ 왼쪽 연산자를 오른쪽 피연산자로 나눈 몫을 구한다. 모든 수치 데이터 타입
% 왼쪽 연산자를 오른쪽 피연산자로 나눈 후의 나머지를 구한다. 모든 수치 데이터 타입

 

 

4.3 증가 연산자와 감소 연산자

피연산자를 하나만 받는 단항 연산자(Unary Operator)라고 한다.

증가/감소 연산자는 변수의 앞에 사용하느냐 또는 뒤에 사용하느냐에 따라 다르다.

변수 뒤에 사용하면 해당 문장의 실행이 끝난 후에 변수의 값이 변경된다. 이를 '후위 증가/감소 연산자' 라고 한다.

변수 앞에 사용하면 변수의 값을 변경한 후에 해당 문장이 실행된다. 이를 '전위 증가/감소 연산자' 라고 한다.

연산자 이름 설명 지원 타입
++ 증가 연산자 피연산자의 값을 1 증가 모든 수치 데이터 타입과 열거 타입
-- 감소 연산자 피연산자의 값을 1 감소 모든 수치 데이터 타입과 열거 타입

 

int a = 10;
Console.WriteLine(a++); // 10 출력 후, 11로 증가
Console.WriteLine(++a); // 12로 증가 후, 12 출력
Console.WriteLine(a--); // 12 출력 후, 11로 감소
Console.WriteLine(--a); // 10 으로 감소 후, 10 출력

 

4.4 문자열 결합 연산자

'+' 를 사용한다.

string result = "1" + "2" + "3"; result는 "123" 이 된다.
Console.WriteLine(result); // 123 출력

 

4.5 관계 연산자

관계 연산자(Relational Operator)는 두 연산자 사이의 관계를 평가하는 연산자다.

연산자 설명 지원 타입
< 왼쪽 피연산자가 오른쪽 피연산자보다 작으면 참, 아니면 거짓 모든 수치 타입과 열거 타입
> 왼쪽 피연산자가 오른쪽 피연산자보다 크면 참, 아니면 거짓 모든 수치 타입과 열거 타입
<= 왼쪽 피연산자가 오른쪽 피연산자보다 작거나 같으면 참, 아니면 거짓 모든 수치 타입과 열거 타입
>= 왼쪽 피연산자가 오른쪽 피연산자보다 크거나 같으면 참, 아니면 거짓 모든 수치 타입과 열거 타입
== 왼쪽 피연산자가 오른쪽 피연산자와 같으면 참, 아니면 거짓 모든 데이터 타입
!= 왼쪽 피연산자가 오른쪽 피연산자와 다르면 참, 아니며 거짓 모든 데이터 타입, string과 object 타입에 대해서도 가능

 

4.6 논리 연산자

부울 연산(Boolean Operation) 이라고도 하는 논리 연산(Logical Operation)은 참과 거짓으로 이루어진 진리값이 피연산자인 연산을 말한다.

 

논리곱 연산자(&&:AND)

피연산자가 모두 참이어야 참이되고 그 외에는 모두 거짓

A B A&&B
거짓 거짓
거짓 거짓 거짓
거짓 거짓

 

논리합 연산자(||:OR)

피연산자가 하나라도 참이면 참이되고 모두 거짓이면 거짓

A B A||B
거짓
거짓 거짓 거짓
거짓

 

부정 연산자(!:NOT)

피연산자의 진릿값을 반대로 한다.

A !A
거짓
거짓

 

4.7 조건 연산자

조건연산자(Conditional Operator) '?:' 는 피연산자가 3개다.

첫 번째 매개변수인 조건식은 결과가 참 또는 거짓의 논리값이어야 한다.

조건식의 결과가 참이면 두번 째 매개변수가 선택되고, 거짓이면 세 번째 매개변수가 선택된다.

// 조건식 ? 참일때 : 거짓일때
int a = 30;
string result = a == 30 ? "삼십" : "삼십아님"; // result 는 "삼십" 이다.

 

4.8 null 조건부 연산자

C# 6.0에서 도입됐다.

'?.' 가 하는 일은 객체의 맴버에 접근하기 전에 해당 객체가 null인지 검사하여 그 결과가 참(즉, 객체가 null)이면 그 결과로 null을 반환하고, 그렇지 않은 경우에는 뒤에 지정된 멤버를 반환한다.

== 연산자를 이용한 코드 ?. 연산자를 이용한 코드
class Foo
{
    public int member;
}

Foo foo = null;

int? bar;
if(foo == null)
    bar == null;
else
    bar = foo.member;
class Foo
{
    public int member;
}

Foo foo = null;

int? bar;
bar = foo?.member; // foo 객체가 null 이 아니면 member 필드에 접근하게 해준다.

 

'?[]' 도 동일한 기능을 수행한다. 다만 객체의 멤버 접근이 아닌 배열과 같은 컬렉션 객체의 첨자를 이용한 참조에 사용된다.

using System.Collections;
using static System.Console;

namespace PracticeCSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            ArrayList a = null;
            a?.Add("야구"); // a?. 가 null을 반환하므로 Add() 메소드는 호출되지 않음
            a?.Add("축구");
            WriteLine($"Count : {a?.Count}");
            WriteLine($"{a?[0]}");
            WriteLine($"{a?[1]}");

            a = new ArrayList(); // a는 이제 null이 아니다.
            a?.Add("야구");
            a?.Add("축구");
            WriteLine($"Count : {a?.Count}");
            WriteLine($"{a?[0]}");
            WriteLine($"{a?[1]}");
        }
    }
}

 

4.9 비트 연산자

바이트 단위가 대부분의 데이터를 다루기에 용이한 크기지만, 비트 수준에서 데이터를 가공해야 하는 경우가 종종 생긴다.

이를 위한 연산자가 비트 연산자다.

연산자 이름 설명 지원 타입
<< 왼쪽 시프트 연산자 첫 번째 피연산자의 비트를 두 번째 피연산자의 수만큼 왼쪽으로 이동시킨다. 첫 번째 피연산자는 int, uint, long, ulong이며 두 번째 피연산자는 int 타입만 지원한다.
>> 오른쪽 시프트 연산자 첫 번째 피연산자의 비트를 두 번째 피연산자의 수만큼 오른쪽으로 이동시킨다.
& 논리곱(AND) 연산자 두 피연산자의 비트 논리곱을 수행한다. 정수 계열 타입과 bool 타입에 대해 사용할 수 있다.
| 논리합(OR) 연산자 두 피연산자의 비트 논리합을 수행한다.
^ 배타적 논리합(XOR) 연산자 두 피연산자의 비트 배타적 논리합을 수행한다.
~ 보수(NOT) 연산자 피연산자의 비트를 0은 1로, 1은 0으로 반전시킨다. 단항 연산자다. int, uint, long, ulong에 대해 사용할 수 있다.

1. 시프트 연산자

시프트 연산자(Shift Operator)는 비트를 왼쪽이나 오른쪽으로 이동시키는 연산

 

왼쪽 시프트 연산

가장 왼쪽의 밀려나온 비트들은 버리고, 비어 있는 비트에는 0으로 채워넣는다.

 

오른쪽 시프트 연산

방향만 다르고, 왼쪽 시프트 연산과 같다.

 

음수에 대한 오른쪽 시프트 연산

비트를 이동시키는 것은 같지만, 이동시킨 후 빈 자리에 1을 채워 넣는다.

 

시프트 연산자는 산술 연산자처럼 피연산자 두 개를 받는다.

왼쪽 피연산자는 원본 데이터, 오른쪽 피연산자는 옮길 비트 수를 의미한다.

int a = 240;
int r1 = a<<2;
int r2 = a>>2;

2. 비트 논리 연산자

비트 논리 연산(Bitwise Logical Operation)도 데이터의 각 비트에 대해 수행하는 논리 연산이다.

연산자 이름 설명 지원 타입
& 논리곱(AND) 연산자 두 피연산자의 비트에 대해 논리곱을 수행한다. 정수 계열 타입과 bool 타입에 사용할 수 있다.
| 논리합(OR) 연산자 두 피연산자의 비트에 대해 논리합을 수행한다.
^ 배타적 논리합(XOR) 연산자 두 피연산자의 비트에 대해 배타적 논리합을 수행한다.
~ 보수(NOT) 연산자 피연산자의 비트에 대해 0은 1로, 1은 0으로 반전시킨다. 단항 연산자다. int, uint, long, ulong에 사용할 수 있다.

 

 

4.10 할당 연산자

변수 또는 상수에 피연산자 데이터를 할당하는 기능을 한다.

연산자 이름 설명
= 할당 연산자 오른쪽 피연산자를 왼쪽 피연산자에 할당한다.
+= 덧셈 할당 연산자 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; 와 같다.

 

4.11 null 병합 연산자

null 병합 연산자 '??" 는 종종 필요한 변수/객체의 null 검사를 간결하게 만들어주는 역할을 한다.

'??' 연산자는 두 개의 피연산자를 받아들이고 왼쪽 피연산자가 null인지 평가한다.

평가 결과가 null이 아닌 것으로 나타나면 왼쪽 피연산자를 그대로 반환하고, 만약 왼쪽 피연산자가 null인 것으로 평가되면 오른쪽 피연산자를 반환한다.

int? a = null;
Console.WriteLine($"{a ?? 0}"); // a는 null이므로 0 출력

a = 99;
Console.WriteLine($"{a ?? 0}"); // a는 null이 아니므로 99 출력

 

4.12 연산자 우선순위

우선순위 종류 연산자
1 증가/감소 연산자 및 null 조건부 연산자 후위++/-- 연산자, ?., ?[]
2 증가 감소 연산자 전위++/-- 연산자
3 산술 연산자 *, /, %
4 산술 연산자 +, -
5 시프트 연산자 <<, >>
6 관계 연산자 <, >, <=, >=, is, as
7 관계 연산자 ==, !=
8 비트 논리 연산자 &
9 비트 논리 연산자 ^
10 비트 논리 연산자 |
11 논리 연산자 &&
12 논리 연산자 ||
13 null 병합 연산자 ??
14 조건 연산자 ?:
15 할당 연산자 =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=