Language/C#

C# 공부정리 - 기초문법 1 (연산자)

Tarel 2022. 12. 30. 16:23

사칙연산

간단한 사칙연산부터 해보자

static void Main(string[] args)
{
    Console.Write("국어 점수 입력하세요?");
    int kor = int.Parse(Console.ReadLine());
    Console.Write("영어 점수 입력하세요?");
    int eng = int.Parse(Console.ReadLine());
    Console.Write("수학 점수 입력하세요?");
    int math = int.Parse(Console.ReadLine());
    Console.Write("과학 점수 입력하세요?");
    int sci = int.Parse(Console.ReadLine());

    int sum = kor + eng + math + sci;
    float avg = sum / 4f;
}

국어 영어 수학 과학 4개 과목의 점수를 입력받고 그것의 평균을 구하는 알고리즘이다.

 

입력 받은 수를 int로 변환하여 읽어드리고

그렇게 받은 값 4개를 4로 나누어 평균을 구한다.

 

여기서 주의해야할 점이 avg의 끝에서 f라는 접미사를 붙인다는 것이다.

 

산술 연산자

산술연산자는 +, -, *, /, % 로 총 5개의 연산자가 있다

순서대로 덧셈, 뺄셈, 곱셉, 나눗셈, 나머지연산이다.

static void Main(string[] args)
{
    int a = 18;
    int b = 6;
    int c = a + b;
    Console.WriteLine("c: " + c);			//a+b는 24

    Console.WriteLine("100 - 10 = " + (100 - 10));		//100 - 10은 90

    int d = a / b;
    Console.WriteLine("d: " + d);		//a 나누기 b는 3

    int e = a * (b + c);
    Console.WriteLine("e: " + e);		//a 에 b와 c를 더한것을 곱하면 540

    int f = (a + b) % 2;				// 24를 2로 나눈 나머지는 0
    Console.WriteLine("f: " + f);
}

나머지 연산이 조금 생소할 수 있는데 이건 짝수홀수 판별할 때 자주 사용한다.

 

증감 연산자

1만큼 더 올리냐 빼냐의 기능을 한다.

int num = 10;

Console.WriteLine("num: {0}", num++); //후치 연산
Console.WriteLine("num: {0}", num);
Console.WriteLine("num: {0}", ++num); //전치 연산

Console.WriteLine("\nnum: {0}", num--); //후치 연산
Console.WriteLine("num: {0}", num);
Console.WriteLine("num: {0}", --num); //전치 연산

++는 1을 증가, --는 1만큼 감소시킨다.

부호가 앞에 있으면 전치연산, 뒤에 있으면 후치연산인데

이는 이 증감연산자가 어느 타이밍에 실행되어야 하는지를 나타낸다.

보통 후치연산을 많이 사용한다.

위의 코드를 출력하면 다음과 같다.

num: 10
num: 11
num: 12

num: 12
num: 11
num: 10

num의 처음 값은 10이었다.

후치연산은 먼저 10이라는 값을 보여주고 그 다음 값을 더하는 것이다.

때문에 두 번째 콘솔에서 11이 나왔다.

반면 전치연산은 결과를 보여주기 전에 1을 더한다

때문에 세 번째 콘솔에서 12가 나온 것이다.

 

할당 연산자

=,   +=,   -=,   *=,   /=,   %=

할당연산자는 위에 표시된 총 6개가 있다.

겉보기에는 복잡해보이지만 사실 알고 보면 굉장히 단순하다.

 

먼저 = 은 왼쪽의 대상에게 오른쪽 값을 넣는다는 뜻이다.

즉 a = 10; 은 a에다가 10을 넣겠다는 뜻이다.

 

a += 10; 은 a = a + 10 과 같다.

즉 a += 10은 a에다가 10을 넣은 값을 넣어주겠다는 뜻이다.

나머지 할당연산자들도 모두 동일하다.

정리하면

a += 10       a  = a + 10

a -= 10       a  = a - 10

a *= 10       a  = a * 10

a /= 10       a  = a / 10

a %= 10       a  = a % 10

이렇게 정리할 수 있다.

 

관계 연산자

뭐가 더 크냐 작냐를 표현하는 연산자다.

<   >   <=   >=   ==   !=

이렇게 6개가 있다.

먼저 <랑 >는 초과, 미만을 나타내고 =가 붙은 것은 이상과 이하를 나타낸다.

 

문제는 ==과 !=인데

==는 이 연산자 좌 우에 위치한 식이 일치하는가를 묻는 것이고

!=는 반대로 좌 우에 위치한 식이 일치하지 않는가를 묻는 것이다.

 

관계연산자는 이러한 특징상, 그 값이 bool로 출력된다.

예를 들어보자

result = (10 > 1);
Console.WriteLine(result);

10은 1보다 크다.

때문에 result는 true가 된다.

result = (10 < 1);
Console.WriteLine(result);

반대로, 위 식은 거짓이 된다.

 

result = (10 != 1);
Console.WriteLine(result);

하나만 더 해보자

10과 1은 같은 값이 아니다.

고로 위의 result는 true가 된다.

 

 

논리 연산자

&&      ||      !

총 3가지가 있다.

&&는 AND연산이고 ||는 OR 연산이다.

!는 NOT연산이다.

 

AND연산이란, &&의 양 옆으로 있는 식이 둘 다 true면 true를 나타내고

OR연산은 ||의 양 옆으로 있는 식이 둘 중 하나라도 true 면 true를 나타낸다.

NOT연산은 참 거짓을 뒤집는다. 즉 true는 false로, false는 true로 만든다.

 

아래 예시를 보자

static void Main(string[] args)
{
    bool result;
    int a = 100;
    int b = 1000;

    result = (a == 100) && (b == 1000); //true , true
    Console.WriteLine("(a == 100) && (b == 1000): {0}", result);
}

아래 result를 보자, a값은 100이 맞다.

그리고 b값도 1000이 맞다.

a와 b가 모두 참이므로 result는 true가 된다.

 

    bool result;
    int a = 100;
    int b = 1000;
    
    result = (a == 100) && (b == 100); //true , false
    Console.WriteLine("(a == 100) && (b == 100): {0}", result);

같은 식을 살짝 수정해 봤다.

이번에는 b값이 1000임에도 불구하고 b == 100으로 입력되어 있다.

AND연산은 둘 다 true여야지 true가 되기 때문에 result는 false가 된다.

 

조건연산자

위 사진에서 ?가 조건연산자에 해당한다.

사실 위 사진은 삼항연산자로 먼저 조건에 해당하는 식을 작성하고 ?를 붙인 뒤, 조건이 참이면 처리1을, 거짓이면 처리 2를 실행한다.

 

비트연산자와 비트논리 연산자

이건 잘 안쓸것 같지만 일단 알아보고 가자

비트연산자로는 << 와 >>가 있고

비트논리연산자로는 &   |   ^   ~ 가 있다.

 

아무튼 비트란 무엇일까?

숫자 15는 2진수로 1111 이다.

이를 비트로 표현하면 0000 0000   0000 0000   0000 0000   0000 1111 이다.

 

0이 굉장히 많은데, 0은 4개씩 2묶음 그리고 이것이 총 4묶음이 있다.

즉, 비트란 총 32개의 2진수 숫자로 이루어져있다.

 

정리하자면 우리가 흔히 쓰는 십진수 숫자를 이진수로 변환한 다음

그 값을 32개의 2진수 숫자로 표현한 것을 비트라고 보면 된다.

 

 

그렇다면 비트 연잔사와 비트 논리연산자는 무엇을 하는 걸까

두 개의 숫자를 예로 들어보자

int a = 15;		// 0000 0000   0000 0000   0000 0000   0000 1111
int b = 22;		// 0000 0000   0000 0000   0000 0000   0001 0110

위의 두 숫자 a와 b를 비트로 표현해보았다.

이제 이 두 숫자를 기반으로 예시를 만들어 보자

 

int a = 15;		// 0000 0000   0000 0000   0000 0000   0000 1111
int b = 22;		// 0000 0000   0000 0000   0000 0000   0001 0110

int c = a & b;		// 0000 0000   0000 0000   0000 0000   0000 0110 =>  6
int d = a | b;		// 0000 0000   0000 0000   0000 0000   0001 1111 => 31
int e = a ^ b;		// 0000 0000   0000 0000   0000 0000   0001 1001 => 25

int f = a << 2;		// 0000 0000   0000 0000   0000 0000   0011 1100 => 60
int g = a >> 2;		// 0000 0000   0000 0000   0000 0000   0000 0011 =>  3

int h = ~a;		// 1111 1111   1111 1111   1111 1111   1111 0000 => -16

&연산자는, 두 비트를 비교했을 때, 둘 다 1일 경우 1이 되고 둘 중 어느 것도 0이라면 0이 된다.

때문에 a & b 는 위에 나타난 식 처럼 6이 된다.

 

|연산자는, 두 비트를 비교했을 때, 둘 중 하나라도 1이면 1이 된다.

때문에 a | b 는 위에 나타난 식 처럼 31이 된다.

 

^연산자는, 두 비트를 비교했을 때, 서로의 값이 다르면 1, 같으면 0이 된다.

때문에 a ^ b 는 위에 나타난 식 처럼 25가 된다.

 

<< 연산자는, 비트를 숫자만큼 왼쪽으로 밀고 그 빈칸에 0을 넣는 연산이다.

때문에 a << 2는 왼쪽으로 두 칸 밀고 그 빈자리에 0을 넣으면서 60이 된다.

 

>> 연산자는, 비트를 숫자만큼 오른쪽으로 밀고 그 빈칸에 0을 넣는 연산이다.

때문에 a >> 2는 오른쪽으로 두 칸 밀고 그 빈자리에 0을 넣으면서 3이 된다.

참고로 맨 오른쪽의 1은 사라진다.

 

<< 연산자와 >> 연산자는 단순히 밀어버리는 것처럼 보일 수 있지만

<<는 2배씩 증가하는 효과를, >>는 2배씩 감소하는 효과를 보여준다.

때문에 15에 <<를 2번하면 60이, 15에 >>를 2번하면 3(소숫점은 버림)이 나온다.

 

~ 연산자는 NOT 연산으로 1과 0을 뒤집어주는 역할을 한다.

때문에 ~a는 -16이 된다.

참고로 마이너스로 변환 될 때는 1 더 적은 숫자로 표현된다.

양수일 때는 0을 포함해야 되기 때문이다.

 

참고로 (~a) >> 2; 처럼 NOT 하고 비트연산을 해버리면 그 빈자리를 0으로 넣을 수도 있고

1로 넣을 수도 있다.

이 결과는 CPU에 따라 다른 결과가 나올 수 있다.

이는 심각한 문제를 초례할 것으로 보이지만 애초에 비트연산 자체가 잘 안쓰이다보니

실제로 문제가 될 경우는 잘 없을 것 같다.

 

null 병합 연산자

null 값을 체크하는 연산자다.

예시로 확인해보자

int? a = null;
int b = 10;
int result;

result = a ?? b;

result의 값은 10이 된다.

a값이 null이기 때문에 result에는 b의 값이 대입되는 것이다.

 

다른 예시를 보자

int? a = null;
int b = 10;
int? c = null;
int d = 100;
int result;

result = a ?? c ?? d;

a는 null이고 c도 null이다. 고로 result에는 d의 값이 대입된다.

 

만약 아래 식처럼 c가 null이 아니라면 어떨까?

int? a = null;
int? c = 999;
int d = 100;
int result;

result = a ?? c ?? d;

이 경우, result에는 c의 값이 대입된다.