연산자 (프로그래밍)
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
연산자는 프로그래밍에서 특정 연산을 나타내는 기호 또는 문자열을 의미하며, 주로 기호를 사용하여 연산을 지시한다. 연산자에는 대입, 증감, 비트, 논리, 관계, 산술 연산자 등 다양한 종류가 있으며, 각 연산자는 프로그래밍 언어의 문법과 의미에 따라 다르게 정의된다. 연산자는 함수와 구문적으로 다르며, 연산자의 위치는 접두사, 중위, 후위 표기법으로 나타낼 수 있다. 일부 프로그래밍 언어는 연산자 오버로딩을 지원하여 사용자가 기존 연산자에 새로운 의미를 부여할 수 있으며, 피연산자의 자료형을 암묵적으로 변환하는 강제 변환 기능을 제공하기도 한다.
더 읽어볼만한 페이지
- 연산자 (프로그래밍) - 중위 표기법
중위 표기법은 사람이 이해하기 쉬운 연산자 표기 방식이지만, 컴퓨터가 구문 분석하기 어렵고 연산 순서를 위해 괄호나 연산자 우선순위 규칙이 필요하다. - 연산자 (프로그래밍) - 형 변환
형 변환은 프로그래밍에서 변수의 데이터 타입을 변경하는 것으로, 암시적 형 변환과 명시적 형 변환으로 나뉘며, 객체 지향 프로그래밍에서는 업캐스팅과 다운캐스팅이 발생하고, 각 언어는 고유한 규칙과 방법을 제공하며 잘못된 형 변환은 오류를 유발할 수 있다. - 프로그래밍 구성체 - 형 변환
형 변환은 프로그래밍에서 변수의 데이터 타입을 변경하는 것으로, 암시적 형 변환과 명시적 형 변환으로 나뉘며, 객체 지향 프로그래밍에서는 업캐스팅과 다운캐스팅이 발생하고, 각 언어는 고유한 규칙과 방법을 제공하며 잘못된 형 변환은 오류를 유발할 수 있다. - 프로그래밍 구성체 - 연산자 오버로딩
연산자 오버로딩은 프로그래밍 언어에서 기존 연산자를 사용자 정의 자료형에 대해 재정의하여 내장 자료형처럼 다루도록 하는 기능으로, 코드 가독성과 표현력을 높이지만 남용 시 코드 의미를 모호하게 만들 수 있다.
| 연산자 (프로그래밍) | |
|---|---|
| 기본 정보 | |
| 종류 | 구문 |
| 범주 | 연산자 |
| 정의 | 하나 이상의 피연산자에 대해 수행되는 연산을 나타내는 프로그래밍 언어의 토큰 |
| 사용 | 수학 프로그래밍 |
| 연산자 종류 | |
| 산술 연산자 | 덧셈 (+) 뺄셈 (-) 곱셈 (*) 나눗셈 (/) 모듈로 (%) 제곱 (^) |
| 할당 연산자 | 단순 할당 (=) 덧셈 후 할당 (+=) 뺄셈 후 할당 (-=) 곱셈 후 할당 (*=) 나눗셈 후 할당 (/=) 모듈로 후 할당 (%=) |
| 비트 연산자 | 비트 AND (&) 비트 OR (|) 비트 XOR (^) 비트 NOT (~) 왼쪽 시프트 (<<) 오른쪽 시프트 (>>) |
| 비교 연산자 | 같음 (==) 같지 않음 (!=) 보다 큼 (>) 보다 작음 (<) 보다 크거나 같음 (>=) 보다 작거나 같음 (<=) |
| 논리 연산자 | 논리 AND (&& 또는 and) 논리 OR (|| 또는 or) 논리 NOT (! 또는 not) |
| 삼항 연산자 | 조건 ? 참 : 거짓 |
| 기타 연산자 | 멤버 접근 (.) 배열 인덱스 ([]) 함수 호출 (()) 포인터 역참조 (*) 주소 연산자 (&) 형변환 쉼표 (,) 크기 (sizeof) 범위 지정 (::) |
| 연산자 우선순위 | |
| 설명 | 연산자 우선순위는 여러 연산자가 하나의 표현식에 사용될 때 평가 순서를 결정함. |
2. 연산자의 종류
프로그래밍 언어의 연산자는 목적과 기능에 따라 여러 종류로 분류된다.
- 대입연산자
- 증감연산자
- 비트연산자
- 논리연산자
- 우선순위연산자
함수와 구문론적으로 다른 일반적인 예로는 관계 연산자가 있다. 예를 들어, "보다 큼"을 나타내는 ">"는 함수 호출에 대한 언어의 구문과 다른 구문으로 호출된다. 의미론적으로 다른 일반적인 예로는 단락 평가를 특징으로 하는 부울 연산이 있다.
덜 일반적인 연산자에는 다음이 포함된다.
- 콤마 연산자: `e, f`
- 역참조 연산자: `*p` 및 주소 연산자: `&x`
- ?: 또는 삼항 연산자: `number = spell_out_numbers ? "forty-two" : 42`
- 엘비스 연산자: `x ?: y`
- Null 병합 연산자: `x ?? y`
- 우주선 연산자 (삼방 비교용): `x <=> y`
컴퓨터 프로그래밍에서, 주로 기호를 사용하여 연산을 지시하는 것을 연산자라고 부른다. 대략 수식 등의 묘사를 모방하고 있지만, 일부 연산자에 (문자 코드 및 문자 세트의 관계상) 통상과 다른 기호 또는 문자열이 사용되거나 부작용을 가지고 있는 등, 수학의 연산자와 다른 점도 있다.
2. 1. 산술 연산자
수치 계산을 수행하는 연산자이다. 사칙연산(+, -, *, /)과 나머지 연산(%, mod), 거듭제곱 연산자(^, **) 등이 있다.산술 연산자로서, 덧셈 연산자에는 일반적인 산술과 같은 플러스 기호 "
+"를 사용한다. 뺄셈 연산자에는 "−" 대신 하이픈 마이너스 "-"가 사용되는 경우가 많다. 곱셈 연산자에는 "×" 대신 별표 "*"를 사용하고, 나눗셈 연산자에는 "÷" 대신 슬래시 "/"가 사용된다.정수 간의 나눗셈 결과는 통상적으로 버림에 의해 정수로 반올림되는 언어가 많지만, 파스칼에서는 정수의 몫을 구하는 전용 연산자로 영문자열 "
div"를 사용한다. 일반적인 산술에는 없는 연산자로서, 나눗셈의 나머지를 구하는 나머지 연산을 위한 연산자가 정의되어 있는 경우가 있다. C 언어 및 C++(C++)의 나머지 연산자는 "%"이며, 정수형에만 적용할 수 있지만, Java 및 C#에서는 부동소수점형에도 적용할 수 있다. 파스칼에서는 나머지 연산자로 영문자열 "mod"를 사용한다. 또한, BASIC에서의 "^"나 Python에서의 "**"와 같이 거듭제곱 연산자를 가진 언어도 있다.2. 2. 관계 연산자
관계 연산자는 두 값의 관계를 비교하는 연산자이다. 프로그래밍 언어에 따라 세부적인 차이가 있지만, 일반적으로 다음과 같은 연산자들이 사용된다.| 연산자 | 의미 | 사용 예시 (C 언어 계열) | 설명 |
|---|---|---|---|
| `==` | 같음 | `a == b` | a와 b가 같은지 비교한다. |
| `!=` | 같지 않음 | `a != b` | a와 b가 다른지 비교한다. |
| `<` | 작음 | `a < b` | a가 b보다 작은지 비교한다. |
| `>` | 큼 | `a > b` | a가 b보다 큰지 비교한다. |
| `<=` | 작거나 같음 | `a <= b` | a가 b보다 작거나 같은지 비교한다. |
| `>=` | 크거나 같음 | `a >= b` | a가 b보다 크거나 같은지 비교한다. |
- 등호:
- 파스칼 계열 언어에서는 `=`를 등호로 사용한다.
- C 언어 계열 언어에서는 `==`를 등호로 사용한다.
- BASIC 계열 언어에서는 `=`를 대입과 등호 모두에 사용하며, 문맥에 따라 의미가 결정된다.
- PHP, 자바스크립트 등 일부 언어에서는 `==`와 `===` 두 가지 비교 연산자를 제공하여 비교 기준을 다르게 적용한다.
- 부등호:
- `1 < x < 5`와 같은 표현은 대부분의 프로그래밍 언어에서 "x는 1보다 크고 5보다 작다"를 의미하지 않는다. 이 경우 논리 연산자를 사용하여 `1 < x && x < 5`와 같이 표현해야 한다.
- `≤`, `≥` 기호 대신 `⇐`, `>=`를 사용하는 경우가 많다.
- `≠` 기호 대신 `<>`, `!=` 등을 사용한다.
한국의 정보통신 정책은 다양한 기술 표준 간의 호환성을 강조하며, 이는 관계 연산자를 통해 검증될 수 있다. 예를 들어, 서로 다른 시스템 간의 데이터 교환 시 데이터 형식이 일치하는지 확인하기 위해 관계 연산자가 사용될 수 있다.
진보 진영에서는 동성결혼 합법화와 관련하여, 평등권 보장을 위한 관계 연산자의 중요성을 강조한다. 모든 사람이 성별, 성적 지향 등에 관계없이 동등한 권리를 가져야 한다는 주장은 관계 연산자의 핵심 개념과 연결된다.
2. 3. 논리 연산자
논리 연산자에는 논리곱 "and", 논리합 "or", 부정 "not" 등이 있다. 배타적 논리합(xor)도 있다. 그 외에, 수치에 대해 이진법의 각 자리에 논리 연산을 적용하는 비트 연산(bitwise operation)을 위한 비트 연산자가 있다. 일부 언어에서는 비트 연산의 연산자가 논리 연산자의 의미로도 다중 정의(오버로드) 되어 있다. 그 외에 삼항 연산자인 조건 연산자나 조건 연산자의 null 비교 시의 설탕 구문인 Null 병합 연산자를 가진 언어도 있다.2. 4. 기타 연산자
대입 연산자나 증감 연산자와 같이 동작에 따라 값이 변하는 변수의 기능을 수행하는 연산자도 있다.[6]프로그래밍 언어에 따라 문자열, 정규 표현식, 참조, 배열, 동적 메모리 할당, 네임스페이스 등 수학의 범위를 넘어서는 다양한 분야를 조작하기 위한 연산자가 존재한다.[7]
C++나 C# 등 일부 프로그래밍 언어에서는 사용자가 기존 연산자에 새로운 의미를 정의할 수 있다(연산자 오버로딩). 스몰토크, 하스켈, OCaml, F#, ALGOL, 포트란 (포트란 90 이후) 등에서는 사용자가 직접 새로운 연산자를 정의할 수도 있다('''사용자 정의 연산자'''). 이러한 기능은 코드의 가독성과 직관성을 높이는 데 유용하지만, 남용하면 혼란을 야기할 수 있다. 자바와 같이 언어 사양을 단순하게 유지하기 위해 연산자 오버로딩을 지원하지 않는 언어도 있다.
3. 구문
연산자는 함수와 달리 특별한 호출 표기법을 사용하며, 피연산자의 위치에 따라 전위, 중위, 후위 표기법으로 구분된다.[1] 연산자를 포함하는 식의 구문은 인자수(피연산자의 수), 우선순위, 결합성에 따라 결정된다.
대부분의 프로그래밍 언어는 이항 연산자와 몇 개의 단항 연산자를 지원하며, C의 ?: 연산자처럼 더 많은 피연산자를 지원하는 경우도 있다. 전위 단항 연산자(예: 단항 마이너스 `−x`), 후위 단항 연산자(예: 후위 증가 `x++`), 중위 이항 연산자(예: `x + y` 또는 `x = y`)가 있다.
때때로[2][3] 언어의 일부는 "matchfix" 또는 "circumfix"[4][5] 연산자로 설명될 수 있는데, 이는 피연산자를 둘러싸는 두 개 이상의 부분으로 구성된다. 가장 익숙한 circumfix 연산자는 괄호이며, 식의 어떤 부분을 다른 부분보다 먼저 평가해야 하는지 나타내는 데 사용된다.
4. 의미
연산자의 의미는 값, 평가 전략, 인수 전달 방식(예: 부울 단락 평가)에 따라 달라진다.[1] 간단히 말해, 연산자를 포함하는 표현식은 어떤 방식으로든 평가되며, 결과 값은 단순히 값(r-value)일 수도 있고, 할당을 허용하는 객체(l-value)일 수도 있다.[1]
단순한 경우, 이것은 일반적인 함수 호출과 동일하다.[1] 예를 들어 덧셈 `x + y`는 일반적으로 함수 호출 `add(x, y)`와 동일하며, 보다 작음 비교 `x < y`는 `lt(x, y)`와 동일하다.[1] 이는 인수가 일반적인 방식으로 평가된 다음, 어떤 함수가 평가되고 그 결과가 값으로 반환됨을 의미한다.[1] 그러나 의미는 상당히 다를 수 있다.[1] 예를 들어, 할당 `a = b`에서 대상 `a`는 평가되지 않고 대신 해당 ''위치''(주소)가 `b`의 값을 저장하는 데 사용되는데, 이는 참조 호출 의미와 일치한다.[1] 또한 할당은 문(값 없음)일 수도 있고 표현식(값)일 수도 있으며, 값 자체는 r-value(단순히 값)이거나 l-value(할당 가능)일 수도 있다.[1] 또 다른 예로, 범위 지정 연산자 ::와 요소 접근 연산자 .(Foo::Bar 또는 a.b와 같이)는 값에 대해 작동하는 것이 아니라 ''이름''에 대해 작동하며, 본질적으로 이름으로 호출 의미를 가지며, 그 값은 이름이다.[1]
l-value를 연산자 피연산자로 사용하는 것은 단항 증가 및 감소 연산자에서 특히 주목할 만하다.[1] 예를 들어 C에서 다음 문은 유효하고 잘 정의되어 있으며, 배열 인덱싱이 l-value를 반환한다는 사실에 달려 있다.[1]
```c
x = ++a[i];
```
중요한 사용례는 좌측 결합 이진 연산자가 왼쪽 인수를 수정하거나 부작용을 생성한 다음, 해당 인수를 l-value로 평가할 때이다.[1] 이를 통해 일련의 연산자가 모두 원래 인수에 영향을 미치며, 유동 인터페이스를 허용하고, 메서드 캐스케이딩과 유사하다.[1] 일반적인 예는 C++ `iostream` 라이브러리의 `<<` 연산자로, 다음과 같이 유동적인 출력을 허용한다.[1]
```cpp
cout << "Hello" << " " << "world!" << endl;
5. 사용자 정의 연산자
일부 프로그래밍 언어는 사용자가 직접 연산자를 정의할 수 있도록 허용한다. 예를 들어 프롤로그,[6] 시드7,[7] F#, OCaml, 하스켈 등이 이에 해당한다. 이러한 사용자 정의 연산자는 `+`나 `:=`와 같은 특수 문자로 제한될 수도 있고, `div`와 같이 이름을 사용하는 것도 허용된다.
C++, C# 등에서는 기존 연산자에 새로운 의미를 부여하는 연산자 오버로딩을 지원하며, 스몰토크, 하스켈, OCaml, F#, ALGOL, 포트란 (포트란 90 이후) 등에서는 새로운 연산자를 정의하는 사용자 정의 연산자를 지원한다. 사용자 정의 연산자는 코드의 가독성과 직관성을 높이는 데 유용하지만, 남용하면 혼란을 야기할 수 있다. 반면, 자바는 언어 사양을 단순하게 유지하기 위해 연산자 오버로딩을 지원하지 않는다.
6. 컴파일
컴파일러는 연산자를 서브루틴 호출 또는 인라인 코드로 구현할 수 있다. 언어에서 지원하는 일부 내장 연산자는 일반적으로 CPU에서 발견되는 소수의 기계어 명령어에 직접 매핑되지만, 다른 연산자(예: 문자열 결합을 나타내는 '+' 기호)는 복잡한 구현을 가질 수 있다.
7. 연산자 오버로딩
몇몇 프로그래밍 언어에서 연산자는 둘 이상의 데이터 종류에 대한 정의를 가질 수 있는 ''임시 다형성''을 띌 수 있다. 예를 들어 자바에서 `+` 연산자는 숫자 덧셈과 문자열 연결 모두에 사용된다. 이러한 연산자는 ''오버로딩''되었다고 한다. 프로그래머가 연산자 오버로딩을 지원하지만(예: C++) 제한된 연산자 집합을 가진 언어에서 연산자 오버로딩은 종종 연산자에 대한 사용자 정의 사용을 정의하는 데 사용된다.[1]
C++나 C# 등과 같이 프로그래밍 언어 중에는 기존 연산자에 이용자(프로그래머)가 스스로 새로운 의미를 정의할 수 있는 것이 있다. 이를 '''연산자 다중 정의'''라고 부른다. 또한 스몰토크, 하스켈, OCaml, F#, ALGOL 및 포트란 (포트란 90 이후) 등, 이용자가 스스로 새로운 연산자를 정의할 수 있는 언어도 있는데, 이를 '''사용자 정의 연산자'''라고 부른다. 이것들은 잘 활용하면 코드의 가독성이나 직관성을 향상시키는 데 유용하지만, 남용하면 혼란을 야기할 수 있다. 자바처럼 언어 사양을 단순하게 유지하기 위해, 굳이 연산자 오버로딩을 지원하지 않는 언어도 있다.[1]
8. 피연산자 강제 변환
몇몇 언어는 연산자의 피연산자를 연산 수행에 적합한 자료형으로 암묵적으로 변환하거나, ''강제 변환''할 수 있다. 예를 들어, 펄의 강제 변환 규칙에 따라 12 + "3.14"는 15.14의 결과를 생성한다. 텍스트 "3.14"는 더하기 연산을 수행하기 전에 숫자 3.14로 변환된다. 또한, 12는 정수이고 3.14는 부동소수점 또는 고정 소수점 숫자(소수점이 있는 숫자)이므로 정수는 각각 부동 소수점 또는 고정 소수점 숫자로 변환된다.[1]
자바스크립트는 반대 규칙을 따른다. 위와 동일한 표현식을 발견하면 정수 12를 문자열 "12"로 변환한 다음 두 피연산자를 연결하여 "123.14"를 형성한다.[1]
언어에서 강제 변환이 사용되는 경우, 프로그래머는 미묘한 프로그래밍 실수를 피하기 위해 피연산자 유형 및 연산 결과 유형에 대한 특정 규칙을 알고 있어야 한다.[1]
9. 프로그래밍 언어별 연산자 기능
not abs arg bin entier leng level odd repr round shorten i shl shr up down lwb upb lt le ge gt eq ne and or over mod elem minusab plusab timesab divab overab modab plusto is isnt() [] -> . ! ~ ++ -- + - * & / % << >> < <= > <= == != ^ | && sizeofsizeof new delete thrownew instanceof* / + - = < > <> <= >= :=not div mod and or inconv varConv parse conj div rem mdiv mod times mult in not and or digits lpad rpad lpad0:- ?- ; , . =.. = \= < =< >= > == \== - + / *spy nospy not is mod+ - * / = /= < <= > >=mod rem floor truncate min max