Unity C# 꼭 알아야 할 연산자
Unity 개발자를 위해 기능 면에서 많은 "heavy-lifting"을 수행하고 개발자가 개발 프로세스에 전적으로 집중할 수 있도록 하는 게임 엔진입니다. 주요 프로그래밍 언어로 C#를 활용합니다.
모든 프로그래밍 언어와 마찬가지로 C#은 특수 함수, 유형, 클래스, 라이브러리 등의 배열로 구성되지만 각각 고유한 기능을 가진 특수 기호(연산자) 목록도 있습니다. 이 게시물에서는 이러한 기호를 나열하고 그 기능을 설명하여 다음에 스크립트를 열 때 각 부분이 무엇을 의미하는지 빠르게 이해할 수 있도록 하겠습니다.
C#의 연산자는 피연산자에 대해 어떤 동작을 수행하는 특수 기호입니다.
C#에는 6가지 유형의 내장 연산자가 있습니다. 산술 연산자, 비교 연산자, 부울 논리 연산자, 비트 및 시프트 연산자, 동등 연산자, 기타 연산자입니다. 이 모든 것을 알면 즉시 더 나은 프로그래머가 될 수 있습니다.
1. 산술 연산자
다음 연산자는 숫자형 피연산자로 산술 연산을 수행합니다.
- 단항 ++(증가), --(감소), +(더하기), -(빼기) 연산자
- 이진 * (곱셈), / (나누기), % (나머지), + (덧셈), - (뺄셈) 연산자
증가 연산자 ++
"add one" 연산자(또는 ++)는 += 1을 의미합니다. 즉, 추가 코드를 입력하지 않고도 숫자 값에 정수 하나를 더하는 빠른 방법입니다. 이 연산자는 값 앞이나 뒤에 추가할 수 있으며, 그에 따라 다른 동작이 발생합니다.
//The result of x++ is the value of x before the operation, as the following example shows:
int i = 4;
Debug.Log(i); // output: 4
Debug.Log(i++); // output: 4
Debug.Log(i); // output: 5
//The result of ++x is the value of x after the operation, as the following example shows:
double a = 2.5;
Debug.Log(a); // output: 2.5
Debug.Log(++a); // output: 3.5
Debug.Log(a); // output: 3.5
감소 연산자 --
"subtract one" 연산자는 ++(-= 1)의 반대이며, 숫자 값에서 정수 하나를 뺍니다. 값 앞이나 뒤에 추가할 수도 있습니다.
The result of x-- is the value of x before the operation, as the following example shows:
int i = 4;
Debug.Log(i); // output: 4
Debug.Log(i--); // output: 4
Debug.Log(i); // output: 3
The result of --x is the value of x after the operation, as the following example shows:
double a = 2.5;
Debug.Log(a); // output: 2.5
Debug.Log(--a); // output: 1.5
Debug.Log(a); // output: 1.5
단항 + 및 - 연산자
단항 + 연산자는 피연산자의 값을 반환하고, 단항 - 연산자는 피연산자의 숫자 부정을 계산합니다.
Debug.Log(+5); // output: 5
Debug.Log(-5); // output: -5
Debug.Log(-(-5)); // output: 5
uint a = 6;
var b = -a;
Debug.Log(b); // output: -6
Debug.Log(b.GetType()); // output: System.Int64
Debug.Log(-double.NaN); // output: NaN
곱셈 연산자 *
곱셈 연산자 *는 피연산자의 곱을 계산합니다.
Debug.Log(6 * 3); // output: 18
Debug.Log(1.5 * 3.5); // output: 5.25
Debug.Log(0.1m * 24.4m); // output: 2.44
나누기 연산자 /
나누기 연산자 /는 왼쪽 피연산자를 오른쪽 피연산자로 나눕니다.
피연산자 중 하나가 10진수인 경우 다른 피연산자는 float도 double도 될 수 없습니다. float도 double도 암묵적으로 10진수로 변환할 수 없기 때문입니다. float 또는 double 피연산자를 10진수 유형으로 명시적으로 변환해야 합니다.
Debug.Log(13 / 5); // output: 2
Debug.Log(13 / 5.0); // output: 2.6
int a = 13;
int b = 5;
Debug.Log((double)a / b); // output: 2.6
Debug.Log(16.8f / 4.1f); // output: 4.097561
Debug.Log(16.8d / 4.1d); // output: 4.09756097560976
Debug.Log(16.8m / 4.1m); // output: 4.0975609756097560975609756098
나머지 연산자 %
나머지 연산자 %는 왼쪽 피연산자를 오른쪽 피연산자로 나눈 나머지를 계산합니다.
- 정수형 피연산자의 경우 a % b의 결과는 a - (a / b) * b로 생성된 값입니다.
Debug.Log(5 % 4); // output: 1
Debug.Log(5 % -4); // output: 1
Debug.Log(-5 % 4); // output: -1
Debug.Log(-5 % -4); // output: -1
- 10진수 피연산자의 경우 나머지 연산자 %는 System.Decimal 형식의 나머지 연산자와 동등합니다.
Debug.Log(-5.2f % 2.0f); // output: -1.2
Debug.Log(5.9 % 3.1); // output: 2.8
Debug.Log(5.9m % 3.1m); // output: 2.8
덧셈 연산자 +
덧셈 연산자 +는 피연산자의 합을 계산합니다. 문자열 연결 및 대리자 조합에도 + 연산자를 사용할 수 있습니다.
Debug.Log(6 + 5); // output: 11
Debug.Log(6 + 5.3); // output: 11.3
Debug.Log(6.1m + 5.2m); // output: 11.3
뺄셈 연산자 -
뺄셈 연산자 -는 오른쪽 피연산자를 왼쪽 피연산자에서 뺍니다. 대리자 제거에는 - 연산자를 사용할 수도 있습니다.
Debug.Log(48 - 4); // output: 44
Debug.Log(6 - 5.3); // output: 0.7
Debug.Log(8.5m - 3.3m); // output: 5.2
2. 비교 연산자
< (less than), > (greater than), <= (less than or equal), and >= (크거나 같음) 비교는 관계 연산자라고도 하며 피연산자를 비교합니다. 이러한 연산자는 모든 정수 및 부동 소수점 숫자 유형에서 지원됩니다.
보다 작음 연산자 <
< 연산자는 왼쪽 피연산자가 오른쪽 피연산자보다 작으면 참을 반환하고, 그렇지 않으면 거짓을 반환합니다.
Debug.Log(8.0 < 6.1); // output: False
Debug.Log(6.1 < 6.1); // output: False
Debug.Log(1.0 < 6.1); // output: True
Debug.Log(double.NaN < 6.1); // output: False
Debug.Log(double.NaN >= 6.1); // output: False
연산자보다 크다 >
> 연산자는 왼쪽 피연산자가 오른쪽 피연산자보다 크면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
Debug.Log(8.0 > 6.1); // output: True
Debug.Log(6.1 > 6.1); // output: False
Debug.Log(1.0 > 6.1); // output: False
Debug.Log(double.NaN > 6.1); // output: False
Debug.Log(double.NaN <= 6.1); // output: False
작거나 같음 연산자 <=
<= 연산자는 왼쪽 피연산자가 오른쪽 피연산자보다 작거나 같으면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
Debug.Log(8.0 <= 6.1); // output: False
Debug.Log(6.1 <= 6.1); // output: True
Debug.Log(1.0 <= 6.1); // output: True
Debug.Log(double.NaN > 6.1); // output: False
Debug.Log(double.NaN <= 6.1); // output: False
크거나 같음 연산자 >=
>= 연산자는 왼쪽 피연산자가 오른쪽 피연산자보다 크거나 같으면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
Debug.Log(8.0 >= 6.1); // output: True
Debug.Log(6.1 >= 6.1); // output: True
Debug.Log(1.0 >= 6.1); // output: False
Debug.Log(double.NaN < 6.1); // output: False
Debug.Log(double.NaN >= 6.1); // output: False
3. 부울 논리 연산자
다음 연산자는 bool 피연산자와 논리 연산을 수행합니다.
- 단항 ! (논리 부정) 연산자.
- 이진 & (논리적 AND), | (논리적 OR), ^ (논리적 배타적 OR) 연산자. 이러한 연산자는 항상 두 피연산자를 모두 평가합니다.
- 이진 && (조건부 논리 AND) 및 || (조건부 논리 OR) 연산자. 이러한 연산자는 필요한 경우에만 오른쪽 피연산자를 평가합니다.
논리 부정 연산자 !
단항 접두사 ! 연산자는 피연산자의 논리적 부정을 계산합니다. 즉, 피연산자가 거짓으로 평가되면 참을 생성하고, 피연산자가 참으로 평가되면 거짓을 생성합니다.
bool passed = false;
Debug.Log(!passed); // output: True
Debug.Log(!true); // output: False
논리 AND 연산자 &
& 연산자는 피연산자의 논리적 AND를 계산합니다. x & y의 결과는 x와 y가 모두 참으로 평가되면 참입니다. 그렇지 않으면 결과는 거짓입니다.
& 연산자는 왼쪽 피연산자가 거짓으로 평가되더라도 두 피연산자를 모두 평가하므로 오른쪽 피연산자의 값과 관계없이 연산 결과는 거짓입니다.
bool SecondOperand()
{
Debug.Log("Second operand is evaluated.");
return true;
}
bool a = false & SecondOperand();
Debug.Log(a);
// Output:
// Second operand is evaluated.
// False
bool b = true & SecondOperand();
Debug.Log(b);
// Output:
// Second operand is evaluated.
// True
논리적 배타적 OR 연산자 ^
^ 연산자는 피연산자의 논리적 배타적 OR, 즉 논리적 XOR을 계산합니다. x ^ y의 결과는 x가 참으로 평가되고 y가 거짓으로 평가되거나 x가 거짓으로 평가되고 y가 참으로 평가되는 경우 참입니다. 그렇지 않으면 결과는 거짓입니다. 즉, bool 피연산자의 경우 ^ 연산자는 부등식 연산자 !=와 동일한 결과를 계산합니다.
Debug.Log(true ^ true); // output: False
Debug.Log(true ^ false); // output: True
Debug.Log(false ^ true); // output: True
Debug.Log(false ^ false); // output: False
논리적 OR 연산자 |
| 연산자는 피연산자의 논리적 OR을 계산합니다. x | y의 결과는 x 또는 y가 true로 평가되면 true이고, 그렇지 않으면 false입니다.
| 연산자는 왼쪽 피연산자가 true로 평가되더라도 두 피연산자를 모두 평가하므로 오른쪽 피연산자의 값과 관계없이 연산 결과가 true입니다.
bool SecondOperand()
{
Debug.Log("Second operand is evaluated.");
return true;
}
bool a = true | SecondOperand();
Debug.Log(a);
// Output:
// Second operand is evaluated.
// True
bool b = false | SecondOperand();
Debug.Log(b);
// Output:
// Second operand is evaluated.
// True
조건 논리 AND 연산자 &&
조건부 논리 AND 연산자 &&는 "short-circuiting" 논리 AND 연산자라고도 하며 피연산자의 논리 AND를 계산합니다. x && y의 결과는 x와 y가 모두 참으로 평가되면 참이고, 그렇지 않으면 결과는 거짓입니다. x가 거짓으로 평가되면 y는 평가되지 않습니다.
bool SecondOperand()
{
Debug.Log("Second operand is evaluated.");
return true;
}
bool a = false && SecondOperand();
Debug.Log(a);
// Output:
// False
bool b = true && SecondOperand();
Debug.Log(b);
// Output:
// Second operand is evaluated.
// True
조건부 논리 OR 연산자 ||
조건부 논리 OR 연산자 ||는 "short-circuiting" 논리 OR 연산자라고도 하며 피연산자의 논리 OR을 계산합니다. x || y의 결과는 x 또는 y가 true로 평가되면 true입니다. 그렇지 않으면 결과는 false입니다. x가 true로 평가되면 y는 평가되지 않습니다.
bool SecondOperand()
{
Debug.Log("Second operand is evaluated.");
return true;
}
bool a = true || SecondOperand();
Debug.Log(a);
// Output:
// True
bool b = false || SecondOperand();
Debug.Log(b);
// Output:
// Second operand is evaluated.
// True
4. 비트 연산자와 시프트 연산자
다음 연산자는 정수 숫자형 또는 char형 피연산자에 대한 비트 연산 또는 이동 연산을 수행합니다.
- 단항 ~ (비트 보수) 연산자
- 이진 << (left shift) and >> (오른쪽 이동) 이동 연산자
- 이진 & (논리적 AND), | (논리적 OR), ^ (논리적 배타적 OR) 연산자
비트 보수 연산자 ~
~ 연산자는 피연산자의 각 비트를 반전시켜 비트 보수를 생성합니다.
uint a = 0b_0000_1111_0000_1111_0000_1111_0000_1100;
uint b = ~a;
Debug.Log(Convert.ToString(b, toBase: 2));
// Output:
// 11110000111100001111000011110011
왼쪽 이동 연산자 <<
<< 연산자는 왼쪽 피연산자를 오른쪽 피연산자에 정의된 비트 수만큼 왼쪽으로 이동합니다. 오른쪽 피연산자가 이동 횟수를 정의하는 방법에 대한 정보는 이동 연산자 섹션의 이동 횟수를 참조하세요.
uint x = 0b_1100_1001_0000_0000_0000_0000_0001_0001;
Debug.Log($"Before: {Convert.ToString(x, toBase: 2)}");
uint y = x << 4;
Debug.Log($"After: {Convert.ToString(y, toBase: 2)}");
// Output:
// Before: 11001001000000000000000000010001
// After: 10010000000000000000000100010000
오른쪽 이동 연산자 >>
>> 연산자는 왼쪽 피연산자를 오른쪽 피연산자가 정의한 비트 수만큼 오른쪽으로 이동합니다.
uint x = 0b_1001;
Debug.Log($"Before: {Convert.ToString(x, toBase: 2), 4}");
uint y = x >> 2;
Debug.Log($"After: {Convert.ToString(y, toBase: 2), 4}");
// Output:
// Before: 1001
// After: 10
상위 빈 비트 위치는 다음과 같이 왼쪽 피연산자의 유형에 따라 설정됩니다.
- 왼쪽 피연산자가 int 또는 long 유형인 경우 오른쪽 시프트 연산자는 산술 시프트를 수행합니다. 왼쪽 피연산자의 가장 중요한 비트(부호 비트) 값이 상위 빈 비트 위치로 전파됩니다. 즉, 상위 빈 비트 위치는 왼쪽 피연산자가 음수가 아니면 0으로 설정되고 음수이면 1로 설정됩니다.
int a = int.MinValue;
Debug.Log($"Before: {Convert.ToString(a, toBase: 2)}");
int b = a >> 3;
Debug.Log($"After: {Convert.ToString(b, toBase: 2)}");
// Output:
// Before: 10000000000000000000000000000000
// After: 11110000000000000000000000000000
- 왼쪽 피연산자가 uint 또는 ulong 유형인 경우 오른쪽 이동 연산자는 논리적 이동을 수행합니다. 상위 빈 비트 위치는 항상 0으로 설정됩니다.
uint c = 0b_1000_0000_0000_0000_0000_0000_0000_0000;
Debug.Log($"Before: {Convert.ToString(c, toBase: 2), 32}");
uint d = c >> 3;
Debug.Log($"After: {Convert.ToString(d, toBase: 2), 32}");
// Output:
// Before: 10000000000000000000000000000000
// After: 10000000000000000000000000000
논리 AND 연산자 &
& 연산자는 정수 피연산자의 비트 단위 논리적 AND를 계산합니다.
uint a = 0b_1111_1000;
uint b = 0b_1001_1101;
uint c = a & b;
Debug.Log(Convert.ToString(c, toBase: 2));
// Output:
// 10011000
논리적 배타적 OR 연산자 ^
^ 연산자는 정수 피연산자의 비트 단위 논리적 배타적 OR, 즉 비트 단위 논리적 XOR을 계산합니다.
uint a = 0b_1111_1000;
uint b = 0b_0001_1100;
uint c = a ^ b;
Debug.Log(Convert.ToString(c, toBase: 2));
// Output:
// 11100100
논리적 OR 연산자 |
| 연산자는 정수 피연산자의 비트 단위 논리적 OR을 계산합니다.
uint a = 0b_1010_0000;
uint b = 0b_1001_0001;
uint c = a | b;
Debug.Log(Convert.ToString(c, toBase: 2));
// Output:
// 10110001
5. 등식 연산자
== (동등) 및 != (부등식) 연산자는 피연산자가 같은지 여부를 확인합니다.
등식 연산자 ==
등식 연산자 ==는 피연산자가 같으면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
int a = 1 + 2 + 3;
int b = 6;
Debug.Log(a == b); // output: True
char c1 = 'a';
char c2 = 'A';
Debug.Log(c1 == c2); // output: False
Debug.Log(c1 == char.ToLower(c2)); // output: True
부등식 연산자 !=
부등식 연산자 !=는 피연산자가 같지 않으면 true를 반환하고, 그렇지 않으면 false를 반환합니다. 내장 유형의 피연산자의 경우, 표현식 x != y는 표현식 !(x == y)와 동일한 결과를 생성합니다.
int a = 1 + 1 + 2 + 3;
int b = 6;
Debug.Log(a != b); // output: True
string s1 = "Hello";
string s2 = "Hello";
Debug.Log(s1 != s2); // output: False
object o1 = 2;
object o2 = 2;
Debug.Log(o1 != o2); // output: True
6. 기타 연산자
일반적인 기타 연산자로는 조건 검사를 위한 ?:, 별칭 네임스페이스의 멤버에 액세스하기 위한::, 문자열 보간을 위한 $ 등이 있습니다.
?: 연산자
조건 연산자 ?:는 3항 조건 연산자라고도 하며, 부울 식을 평가하고 부울 식이 참인지 거짓인지에 따라 두 식 중 하나의 결과를 반환합니다. 다음 예에서 알 수 있듯이요.
bool condition = true;
Debug.Log(condition ? 1 : 2); // output: 1
:: 운영자
별칭 네임스페이스의 멤버에 액세스하려면 네임스페이스 별칭 한정자::를 사용합니다.:: 한정자는 두 식별자 사이에서만 사용할 수 있습니다. 왼쪽 식별자는 다음 별칭 중 하나일 수 있습니다.
- using alias 지시문을 사용하여 생성된 네임스페이스 별칭:
using forwinforms = System.Drawing;
using forwpf = System.Windows;
public class Converters
{
public static forwpf::Point Convert(forwinforms::Point point) => new forwpf::Point(point.X, point.Y);
}
- 외부 별칭.
- 전역 별칭은 전역 네임스페이스 별칭입니다. 전역 네임스페이스는 명명된 네임스페이스 내부에서 선언되지 않은 네임스페이스와 유형을 포함하는 네임스페이스입니다.:: 한정자와 함께 사용할 경우 전역 별칭은 사용자 정의 전역 네임스페이스 별칭이 있더라도 항상 전역 네임스페이스를 참조합니다.
namespace MyCompany.MyProduct.System
{
class Program
{
static void Main() => global::System.Console.WriteLine("Using global alias");
}
class Console
{
string Suggestion => "Consider renaming this class";
}
}
$ 연산자
$ 특수 문자는 문자열 리터럴을 보간된 문자열로 식별합니다. 보간된 문자열은 보간 표현식을 포함할 수 있는 문자열 리터럴입니다. 보간된 문자열이 결과 문자열로 해석되면 보간 표현식이 있는 항목은 표현식 결과의 문자열 표현으로 대체됩니다.
보간된 문자열에서 달러 기호($)는 C# 컴파일러에게 뒤에 오는 문자열을 보간된 문자열로 해석해야 한다는 것을 알리는 데 사용됩니다. 중괄호는 텍스트에 포함할 값(변수)을 캡슐화합니다.
문자열 리터럴을 보간된 문자열로 식별하려면 $ 기호를 앞에 붙입니다. $와 문자열 리터럴을 시작하는 " 사이에 공백이 있어서는 안 됩니다.
string name = "John";
var date = DateTime.Now;
Debug.Log($"Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now.");
// Output:
// Hello, John! Today is Wednesday, it's 19:40 now.