본문 바로가기

C#/이것이 C#이다

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

[ 학습 흐름 ]

[ 학습 흐름]

  1. C#에서 제공하는 연산자 둘러보기
  2. 산술 연산자
  3. 증가 연산자와 감소 연산자
  4. 문자열 결합 연산자
  5. 관계 연산자
  6. 논리 연산자
  7. 조건 연산자
  8. 비트 연산자
  9. 할당 연산자
  10. 연산자의 우선순위

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

[ 연산자 ]

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

- 대부분은 각각 특정 형식에 대해서만 사용 가능하다 .


[ 산술 연산자 ]

[ 산술 연산자 ]

- 수치 형식 ( 정수 , 부동 소수점 , decimal ) 의 데이터를 다루는 이항 연산자 .

- 이항 연산자 ( Binary Operator )는 [왼쪽 피연산자] + 연산자 + [오른쪽 피연산자]와 같이 두개의 피연산자가 필요하다 .

- * , / , % 가 +,- 보다 우선으로 처리된다 .

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

namespace ArithmaticOperators;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        int a = 111 + 222;
        Console.WriteLine($"a : {a}");

        int b = -100;
        Console.WriteLine($"b : {b}");

        int c = b * 10;
        Console.WriteLine($"c : {c}");

        //피연산자 중 한쪽이 부동 소수형이면 부동 소수형 버전의 연산자가 사용
        //나머지 피연산자도 부동 소수형으로 형식 변환된다 .
        double d = c / 6.3;
        Console.WriteLine($"d : {d}");

        Console.WriteLine($"22/7 = {22 / 7}({22 % 7})");
    }
}

 


[ 증가 연산자와 감소 연산자 ]

[ 증가 연산자 / 감소 연산자 ]

연산자 이름 설명 지원 형식
++ 증가 연산자 피연산자의 값을 1 증가시킨다 . 모든 수치데이터 형식과 열거형식
-- 감소 연산자 피연산자의 값을 1 감소시킨다 . 모든 수치데이터 형식과 열거형식

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

- 후위 증가/감소 연산자 : 변수 뒤에 사용하면 해당 문장의 실행이 끝난 후에 변수의 값이 변경 .

int a = 10;
int b = 10;
//문장이 끝나고 증가시켜 10이 출력
Console.WriteLine(a++);
//증가후 문장을 시작하니 11이 출력
Console.WriteLine(++b);
using System;

namespace IncDecOperators;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        int a = 10;
        Console.WriteLine(a++);
        Console.WriteLine(++a);

        Console.WriteLine(a--);
        Console.WriteLine(--a);
    }
}

 


[ 문자열 결합 연산자 ]

[ 문자열 결합  연산자 ]

- 문자열과 함께 사용하는 + 는 산술 연산자가 아닌 문자열 결합 연산자이다 .

using System;

namespace StringConcatenate;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        string result = "123" + "456";
        Console.WriteLine(result);

        result = "Hello" + "" + "World!";
        Console.WriteLine(result);
    }
}

 


[ 관계 연산자 ]

[ 관계 연산자 ]

- 관계 연산자는 두 피연산자 사이의 관계를 평가하는 연산자이다 .

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

namespace RelationalOperator;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        Console.WriteLine($"3 > 4 : {3 > 4}");
        Console.WriteLine($"3 >= 4 : {3 >= 4}");
        Console.WriteLine($"3 < 4 : {3 < 4}");
        Console.WriteLine($"3 <= 4 : {3 <= 4}");
        Console.WriteLine($"3 == 4 : {3 == 4}");
        Console.WriteLine($"3 != 4 : {3 != 4}");
    }
}

 


[ 논리 연산자 ]

[ 논리 연산자 ]

- 논리연산은 참과 거짓으로 이루어지는 진릿값이 피연산자인 연산

연산자 이름 설명
&& : AND 논리곱 연산자 두 개의 진릿값이 모두 참이어야 참 . 그 외에는 모두 거짓 .
|| : OR 논리합 연산자 두 개의 진릿값중 하나라도 참이면 참 . 그 외에는 모두 거짓 .
! : NOT 부정 연산자 진릿값을 반대로 뒤집는다
using System;

namespace LogicalOperator;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        //&& Operator
        Console.WriteLine("Testing && Operator");
        Console.WriteLine($"1>0 && 4<5 : {1 > 0 && 4 < 5}");
        Console.WriteLine($"1>0 && 4>5 : {1 > 0 && 4 > 5}");
        Console.WriteLine($"1==0 && 4<5 : {1 == 0 && 4 < 5}");
        Console.WriteLine($"1==0 && 4>5 : {1 == 0 && 4 > 5}");

        //|| Operator
        Console.WriteLine("\nTesting || Operator");
        Console.WriteLine($"1>0 || 4<5 : {1 > 0 || 4 < 5}");
        Console.WriteLine($"1>0 || 4>5 : {1 > 0 || 4 > 5}");
        Console.WriteLine($"1==0 || 4>5 : {1 == 0 || 4 > 5}");
        Console.WriteLine($"1==0 || 4<5 : {1 == 0 || 4 < 5}");

        //! Operator
        Console.WriteLine("\nTesting ! Operator");
        Console.WriteLine($"!True : {!true}");
        Console.WriteLine($"!False : {!false}");
    } 
}

 


[ 조건 연산자 ]

[ 조건 연산자 ]

[ 조건식 ] ? [ 참일때의 값 ] : [ 거짓일때의 값 ]

 

using System;

namespace ConditionalOperator;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        string result = (10 % 2) == 0 ? "짝수" : "홀수";
        Console.WriteLine(result);
    } 
}

 


[ null조건부 연산자 ]

[ null조건부 연산자 : ?. ]

- 객체의 멤버에 접근하기 전에 해당 객체가 null인지 검사 ,

객체가 null 이면 null을 반환하고 아니라면 뒤에 지정된 멤버를 반환한다 . 

class Foo
{
	public int number;
}

Foo foo;
int?bar;

//case 1  ==연산자 사용
if(foo==null)
	bar=null;
else
	bar=foo.number;
    
//case 2  null 조건부 연산자 사용
bar = foo?.number;

[ null조건부 연산자 : ?[ ] ]

- 객체 맴버 접근이 아닌 배열과 같은 컬렉션 객체의 첨자를 이용한 참조에 사용된다 .

using System.Collections;
using static System.Console;

namespace NullConditionalOperator;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        ArrayList? a = null;
        a?.Add("야구");//a?.가 null을 반환하므로 Add()메서드는 호출되지 않음
        a?.Add("축구");
        WriteLine($"Count : {a?.Count}");
        WriteLine($"a[0] : {a?[0]}");
        WriteLine($"a[1] : {a?[1]}");

        a = new ArrayList();
        a?.Add("야구");//a?.가 null을 반환하므로 Add()메서드는 호출되지 않음
        a?.Add("축구");
        WriteLine($"Count : {a?.Count}");
        WriteLine($"a[0] : {a?[0]}");
        WriteLine($"a[1] : {a?[1]}");

    }
}

 


[ 비트 연산 ]

[ 비트 연산자 ]

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

[ 시프트 연산자 ]

- 비트를 이동시킨후 밀려 나온 비트는 버리고 , 비어있는 비트는 0으로 채운다 .

- 음수에 대한 오른쪽 시프트 연산은 비어있는 비트를 1로 채운다 .

- 원본 데이터를 a / 옮긴 비트수를 b라 할때 , 오른쪽 시프트 연산을 하면  a x 2b승 / 왼쪽 시프트 연산을 하면 a % 2b승가 된다.

- 고속의 곱셈/나눗셈 구현에 사용한다 .

- &,|연산자와 함께 byte처럼 작은 단위로 쪼개진 데이터를 하나의 int,long 형식으로 재조립 하는데 사용한다 .

using System;
using System.Collections;
using static System.Console;

namespace ShiftOperator;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        Console.WriteLine("Testing Shift Operator ---------------- ");

        int a = 1;
        //1바이트로 나타낼 수 있는 수는 256개 . 8자리의 16진수는 int 형식이 표현 할 수 있는 모든 수를 나타낼 수 있다 .
        Console.WriteLine("a     : {0:D5} (0x{0:x8})", a);
        Console.WriteLine("a <<1 : {0:D5} (0x{0:x8})", a<<1);
        Console.WriteLine("a <<2 : {0:D5} (0x{0:x8})", a<<2);
        Console.WriteLine("a <<5 : {0:D5} (0x{0:x8})", a<<5);
        Console.WriteLine("Testing----------------\n");

        int b = 255;      
        Console.WriteLine("b     : {0:D5} (0x{0:x8})", b);
        Console.WriteLine("b >>1 : {0:D5} (0x{0:x8})", b >> 1);
        Console.WriteLine("b >>2 : {0:D5} (0x{0:x8})", b >> 2);
        Console.WriteLine("b >>5 : {0:D5} (0x{0:x8})", b >> 5);
        Console.WriteLine("Testing----------------\n");

        int c = -255;        
        Console.WriteLine("c     : {0:D5} (0x{0:x8})", c);
        Console.WriteLine("c >>1 : {0:D5} (0x{0:x8})", c >> 1);
        Console.WriteLine("c >>2 : {0:D5} (0x{0:x8})", c >> 2);
        Console.WriteLine("c >>5 : {0:D5} (0x{0:x8})", c >> 5);      
    }
}

 


[ 비트 논리 연산자 ]

- & (논리곱 연산자) : 둘다 참(1)이어야 참(1) 아니라면 거짓 (0)

- |(논리합 연산자) : 둘 중 하나라도 참(1)이면 참(1) 아니라면 거짓(0)

- ^(배타적 논리합 연산자) : 둘이 서로 달라야 참(1) 아니라면 거짓(0)

- ~(보수 연산자) : 피연산자의 비트를 참(1)은 거짓(0) , 거짓(0)은 참(1)으로 반전 .

using System;
using System.Collections;
using static System.Console;

namespace BitwiseOperator;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        int a = 9;
        int b = 10;

        Console.WriteLine($"{a} & {b} : {a&b}");
        Console.WriteLine($"{a} | {b} : {a | b}");
        Console.WriteLine($"{a} ^ {b} : {a ^ b}");

        int c = 255;
        Console.WriteLine("~{0} (0x{0:X8}) : {1}(0x{1:X8})", c, ~c);

    }
}

 


[ 할당 연산자 ]

[ 할당 연산자 ]

연산자 이름 설명
= 할당 연산자 오른쪽 피연산자를 왼쪽 피연산자에 할당합니다 .
+= 덧셈 할당 연산자 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와 같음 .
using System;
using System.Collections;
using static System.Console;

namespace AssignmentOperator;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        int a;
        a = 100;
        Console.WriteLine($"a=100 : {a}");
        a += 90;
        Console.WriteLine($"a+=90 : {a}");
        a -= 80;
        Console.WriteLine($"a-=80 : {a}");
        a *= 70;
        Console.WriteLine($"a *= 70 : {a}");
        a /= 60;
        Console.WriteLine($"a /= 60 : {a}");
        a %= 50;
        Console.WriteLine($"a %= 50 : {a}");
        a &= 40;
        Console.WriteLine($"a &= 40 : {a}");
        a |= 30;
        Console.WriteLine($"a |= 30 : {a}");
        a ^= 20;
        Console.WriteLine($"a ^= 20 : {a}");
        a <<= 10;
        Console.WriteLine($"a <<= 10 : {a}");
        a >>= 1;
        Console.WriteLine($"a >>= 1 : {a}");
    }
}

 


[ null 병합 연산자 ]

[ null 병합 연산자 ]

- 변수/객체의 null 검사를 간결하게 만들어주는 역할을 한다 .

- 왼쪽 피연산자가 null인지 확인 , null이라면 오른쪽 피연간자를 아니라면 왼쪽 피연산자를 그대로 반환한다 .

using System;
using System.Collections;
using static System.Console;

namespace NullCoalescing;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        int? num = null;
        Console.WriteLine($"{num ?? 0}");

        num = 99;
        Console.WriteLine($"{num ?? 0}");

        string str = null;
        Console.WriteLine($"{str ?? "Default"}");
        str = "Specific";
        Console.WriteLine($"{str ?? "Default"}");
    }
}

 


[ 연산자의 우선순위 ]

[ 연산자 우선순위 ]

- 산술, 비교, 논리, 대입 연산자 순으로 우선순위를 가진다.

- 단항, 이항, 삼항 연산자 순으로 우선순위를 가진다.

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