끝나지 않는 프로그래밍 일기


1. 연산자(Operators)

C#에선 산술 연산자, 증감 연산자, 조건 연산자, 관계 연산자, 논리 연산자 등 여러 가지의 연산자를 제공합니다. 오늘은 아래 표에 정리된 연산자들에 대해서 배워보도록 하겠습니다.

분류 

연산자

예 

수식 연산자 

+, -, *, /, % 

a = b + c; 

증감 연산자 

++, -- 

a++; 

할당 연산자 

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

a += b + c;

논리 연산자 

&&, ||, ! 

a && b 

관계 연산자 

<, >, ==, !=, >=, <=

a > b 

비트 연산자

&, |, ^ 

a ^ b 

시프트 연산자

>>, <<

a >> 2 

2. 수식 연산자(+, -, *, /, %)

수식 연산자에는 덧셈, 뺄셈, 곱셈, 나눗셈, 그리고 나눗셈을 한 뒤의 나머지를 구하는 연산자들이 있습니다. 아래는 그 연산자들을 표로 정리한 것입니다.

분류 

기능 

예 

양쪽 피연산자를 서로 더함 

a + b 

왼쪽 피연산자에서 오른쪽 피연산자를 뺌 

a - b 

*

양쪽 피연산자를 서로 곱함 

a * b 

/

왼쪽 피연산자를 오른쪽 피연산자로 나눔 

a / b

%

왼쪽 피연산자를 오른쪽 피연산자로 나눈 뒤의 나머지를 구함 

a % b

여기서, 피연산자란 연산의 대상을 말합니다. 예를 들어서, a + b라면 a와 b는 피연산자고 +는 연산자입니다.


아래는 수식 연산자를 사용하여 그 결과를 출력하는 예제입니다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 55, b = 4;

            Console.WriteLine("{0} + {1} = {2}", a, b, a + b);
            Console.WriteLine("{0} - {1} = {2}", a, b, a - b);
            Console.WriteLine("{0} * {1} = {2}", a, b, a * b);
            Console.WriteLine("{0} / {1} = {2}", a, b, a / b);
            Console.WriteLine("{0} % {1} = {2}", a, b, a % b);
        }
    }
}
결과:
55 + 4 = 59
55 - 4 = 51
55 * 4 = 220
55 / 4 = 13
55 % 4 = 3
계속하려면 아무 키나 누르십시오 . . .
예제 코드와 결과를 비교해보시면 예상했던 대로 값이 출력됨을 확인할 수 있습니다. 하나만 제외하고 말이죠! 왜 55를 4으로 나눴을 때 13.75가 아니라 13만 출력되는 것일까요? 그 이유는 정수 간 나눗셈은 항상 정수로만 나타나기 때문에, 아래와 같이 제수나 피제수 중 하나를 실수 타입(float, double, decimal)로 변환해 주어야 원하는 값을 얻을 수 있습니다.
...
Console.WriteLine("{0} / {1} = {2}", a, b, a / (double)b);
Console.WriteLine("{0} / {1} = {2}", a, b, (a + 0.0) / b);
Console.WriteLine("{0} / {1} = {2}", a, b, 1.0 * a / b);
...

일종의 꼼수이기는 하지만 위와 같은 방법으로 문제를 해결할 수 있습니다. 

3. 증감 연산자(++, --)
증감 연산자에는 피연산자의 값을 1만큼 증가시키는 증가 연산자와, 1만큼 감소시키는 감소 연산자가 있습니다.

분류

기능

++ (전위 증가 연산자)

피연산자의 값을 1만큼 증가

++a;

-- (전위 감소 연산자)

피연산자의 값을 1만큼 감소

--a;

++ (후위 증가 연산자)

피연산자의 값을 1만큼 증가

a++;

-- (후위 감소 연산자)

피연산자의 값을 1만큼 감소

a--;

아래는 증감 연산자를 사용하여 그 결과를 출력하는 예제입니다.

using System;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 1;

            Console.WriteLine(++a); // a의 값을 1 증가시키고, a의 값을 출력 (a = 2)
            Console.WriteLine(a++); // a의 값을 출력한 뒤, a의 값을 1 증가 (a = 3)
            Console.WriteLine(--a); // a의 값을 1 감소시키고, a의 값을 출력 (a = 2)
            Console.WriteLine(a--); // a의 값을 출력한 뒤, a의 값을 1 감소 (a = 1)
        }
    }
}
결과:
2
2
2
2
계속하려면 아무 키나 누르십시오 . . .
전위는 우선 피연산자의 값을 증가시키거나 감소하고 그 문장을 실행하며, 후위는 문장을 먼저 실행하고 그 뒤로 값을 증가시키거나 감소하는 차이점을 보입니다. 

예를 들어서, a가 3이고 b가 5일 때 아래 연산식의 결과를 각각 예상해봅시다.
a++ + b
a++ + --b
++a + a++
(1) a++ + b의 결과는 8이며, 계산이 끝난 뒤의 값은 a = 4, b = 5 입니다. a에 후위 증가 연산자가 사용되었으므로 계산이 끝나고 난 뒤에야 a의 값이 증가합니다. 
(2) a++ + --b의 결과는 7이며, 계산이 끝난 뒤의 값은 a = 4, b = 4입니다. a에 후위 증가 연산자가 사용되었으므로 계산이 끝나고 난 뒤에야 a의 값이 증가하고, b에 전위 감소 연산자가 사용되었으므로 b의 값이 먼저 감소하고 계산이 됩니다. 
(3) ++a + a++의 결과는 8이며, 계산이 끝난 뒤의 값은 a = 5입니다. 연산의 순서는 왼쪽에서 오른쪽으로 계산된다는 것을 생각하고 있어야 합니다. 먼저 ++a는 a의 값이 3에서 4로 증가하고, 증가한 값인 4가 그대로 계산에 쓰입니다. a++도 마찬가지로 a의 값이 4에서 5로 증가하지만, 증가되기 이전의 값인 4가 계산에 쓰입니다. 결국에는 4 + 4이므로 8이 나오는 것입니다.
4. 관계 연산자(<, >, ==, !=, >=, <=)
관계 연산자는 두 피연산자의 관계를 알아보는 연산자인데, 크기를 비교하는 연산자, 두 피연산자의 값이 서로 같거나 다른지 확인하는 연산자가 있습니다. 아래는 관계 연산자를 표로 정리해 둔 것입니다.

분류

기능

<

오른쪽 피연산자가 왼쪽 피연산자보다 크면 참, 작으면 거짓

a < b

>

왼쪽 피연산자가 오른쪽 피연산자보다 크면 참, 작으면 거짓

a > b

==

왼쪽 피연산자가 오른쪽 피연산자와 같으면 참, 다르면 거짓

a == b

!=

왼쪽 피연산자가 오른쪽 피연산자와 다르면 참, 같으면 거짓

a != b

>=

왼쪽 피연산자가 오른쪽 피연산자보다 크거나 같으면 참, 작으면 거짓

a >= b

<=

오른쪽 피연산자가 왼쪽 피연산자보다 크거나 같으면 참, 작으면 거짓

a <= b

아래 예제는 관계 연산자를 사용하여 결과를 출력하는 예제입니다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 50, b = 60;

            Console.WriteLine(a < b); // 50 < 60, True
            Console.WriteLine(a > b); // 50 > 60, False
            Console.WriteLine(a == b); // 50 == 60, False
            Console.WriteLine(a != b); // 50 != 60, True
            Console.WriteLine(a >= b); // 50 >= 60, False
            Console.WriteLine(a <= b); // 50 <= 60, True
        }
    }
}
결과:
True
False
False
True
False
True
계속하려면 아무 키나 누르십시오 . . .
* 관계 연산자의 결과는 반드시 참(True) 혹은 거짓(False)입니다. 
5. 할당 연산자(=, +=, -=, *=, /=, %=)
할당 연산자는 오른쪽 피연산자를 왼쪽 피연산자에 할당하는 기능을 합니다. 아래는 할당 연산자를 표로 정리해 둔 것입니다.

분류 

기능 

예 

=

오른쪽 피연산자를 왼쪽 피연산자에 할당

a = b; 

+= 

a += b는 a = a + b와 같음

a += b; 

-= 

a -= b는 a = a - b와 같음 

a -= b; 

*= 

a *= b는 a = a * b와 같음

a *= b; 

/= 

a /= b는 a = a / b와 같음

a /= b; 

%= 

a %= b는 a = a % b와 같음

a %= b; 

아래는 할당 연산자를 사용하여 그 값을 출력하는 예제입니다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 50, b = 60;

            a += b;
            Console.WriteLine(a);
            a -= b;
            Console.WriteLine(a);
            a *= b;
            Console.WriteLine(a);
            a /= b;
            Console.WriteLine(a);
            a %= b;
            Console.WriteLine(a);
        }
    }
}
결과:
110
50
3000
50
50
계속하려면 아무 키나 누르십시오 . . .
6. 논리 연산자(&&, ||, !)
논리 연산자는 위에서 배운 관계 연산자 처럼 결과 값이 true 또는 false이 되는 연산자 입니다. 아래의 표들은 논리곱(AND) 연산자, 논리합(OR) 연산자, 부정(NOT) 연산자의 진리표입니다.

A && B 

참(T)

참(T) 

참(T) 

참(T) 

거짓(F)

거짓(F) 

거짓(F) 

참(T)

거짓(F)

거짓(F) 

거짓(F)

거짓(F) 

<논리곱 연산자(&&)의 진리표>

논리곱(AND) 연산자의 특징은 A와 B 모두 참이여야 결과값으로 참을 반환합니다. 

A || B 

참(T) 

참(T) 

참(T) 

참(T) 

거짓(F) 

참(T) 

거짓(F) 

참(T) 

참(T) 

거짓(F) 

거짓(F) 

거짓(F) 

<논리합 연산자(||)의 진리표>

논리합(OR) 연산자의 특징은 A나 B 둘중 하나라도 참일 경우에 결과값으로 참을 반환합니다.

!A 

참(T) 

거짓(F) 

거짓(F) 

참(T) 

<부정 연산자(!)의 진리표>

부정(NOT) 연산자의 특징은 A가 참일 경우에 거짓을, 거짓일 경우에는 참을 결과값으로 반환합니다.


아래는 논리 연산자를 사용하여 그 결과를 출력한 예제입니다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 50, b = 60;

            Console.WriteLine(a > 40 && b > 50);
            Console.WriteLine(a > 40 || b > 70);
            Console.WriteLine(!(a < b));
        }
    }
}
결과:
True
True
False
계속하려면 아무 키나 누르십시오 . . .
예제를 살펴보면, 11행에서 논리곱(AND) 연산자가 쓰였는데 a > 40은 참, b > 50도 참이므로 참을 결과값으로 반환합니다. 12행에서는 논리합(OR) 연산자가 쓰였으며 a > 40은 참, b > 70은 거짓이나 논리합 연산자는 하나라도 참일 경우에 참을 결과값으로 반환하므로 참이 출력됩니다. 13행에선 부정(NOT) 연산자가 쓰였습니다. a < b는 원래 참이나 부정 연산자로 인해 결과를 부정하여 거짓을 결과값으로 반환하였습니다.
7. 비트 연산자(&, |, ^)
비트 연산자는 말 그대로 비트를 다루는 데 사용되는 연산자입니다. 아래의 표는 비트 연산자를 정리해 둔 것입니다.

분류

기능 

예 

두 피연산자의 대응되는 비트에 논리곱(AND)을 수행

a & b 

두 피연산자의 대응되는 비트에 논리합(OR)을 수행

a | b 

두 피연산자의 대응되는 비트에 배타적 논리합(XOR)을 수행

a ^ b 

여기서 & 연산자는 양쪽 비트가 모두 1이어야만 결과가 1이 되고, 그렇지 않으면 결과가 0이 됩니다. | 연산자는 양쪽 비트 중 하나라도 1이면 결과가 1이 됩니다. ^ 연산자는 양쪽 비트가 서로 달라야 결과가 1이 됩니다. 감이 잘 안오시나요? 예제를 바로 봐보도록 합시다.


아래는 비트 연산자를 사용하여 그 결과를 출력하는 예제입니다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 5, b = 10;

            Console.WriteLine(a & b);
            Console.WriteLine(a | b);
            Console.WriteLine(a ^ b);
        }
    }
}

결과:

0

15

15

계속하려면 아무 키나 누르십시오 . . .


위의 결과가 어떻게 해서 이렇게 나왔는지 아래에서 확인하실 수 있습니다. 10진수 5를 2진수로 나타내면 101(2), 10진수 10을 2진수로 나타내면 1010(2)와 같습니다.


7. 시프트 연산자 (>>, <<)

시프트 연산자도 비트 연산과 관련된 연산자입니다. 이 연산자를 통해 첫 번째 피연산자를 두 번째 피연산자로 지정된 비트 수만큼 왼쪽(<<)으로 이동시키거나 오른쪽(>>)으로 이동시킬 수 있습니다.


아래는 시프트 연산자를 사용하여 그 결과를 출력하는 예제입니다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 616;

            Console.WriteLine(a << 4);
            Console.WriteLine(a >> 4);
        }
    }
}

결과:

9856

38

계속하려면 아무 키나 누르십시오 . . .

우선, 616을 2진수로 나타내면 1001101000(2) 입니다. 이 비트열을 왼쪽으로 4만큼 이동시키면 아래와 같이 10011010000000(2)가 될 것입니다. 이는 10진수로 나타내면 9856 입니다. 비트열을 왼쪽으로 이동시키면서 새로 나타난 하위 비트는 0으로 채워집니다.

다시 기존 비트열을 오른쪽으로 4만큼 이동시키면 아래와 같이 100110(2)이 될 것입니다. 이는 10진수로 나타내면 38 입니다. 비트열을 오른쪽으로 이동시키면서 새로 나타난 상위 비트는 부호 비트로 채워집니다. (부호 비트는 양수의 경우는 0, 음수의 경우는 1)

다음은 분기문(if, else, switch)에 대해 알아보도록 하겠습니다. 수고하셨습니다.