C와 C++의 연산자
Operators in C and C++이것은 C와 C++ 프로그래밍 언어의 연산자 목록입니다. C++에는 나열된 모든 연산자(종류를 제외하고)가 존재합니다. 열 "C에 포함됨"은 연산자가 C에도 존재하는지 여부를 나타냅니다. C는 연산자 과부하를 지원하지 않습니다.
오버로드되지 않은 경우, 연산자에 대해 &&
,
,그리고. ,
(콤마 연산자), 첫 번째 피연산자의 평가 후에 시퀀스 포인트가 있습니다.
C++에는 유형 변환 연산자도 포함됩니다. const_cast
, static_cast
, dynamic_cast
,그리고. reinterpret_cast
. 이러한 연산자의 형식은 우선 순위 수준이 중요하지 않다는 것을 의미합니다.
C와 C++에서 사용할 수 있는 대부분의 연산자는 C#, D, Java, Perl, PHP와 같은 다른 C 패밀리 언어에서도 동일한 우선순위, 연관성 및 의미론을 사용할 수 있습니다.
테이블
이 테이블의 목적을 위해, a
, b
,그리고. c
적합한 경우 유효한 값(영문, 변수의 값 또는 반환 값), 개체 이름 또는 l 값을 나타냅니다. R
, S
그리고. T
모든 유형을 나타냅니다. K
클래스 유형 또는 열거된 유형의 경우.
산술 연산자
모든 산술 연산자는 C와 C++에 존재하며 C++에서 과부하가 가능합니다.
작업자명 | 구문 | C++ 시제품 예제 | ||
---|---|---|---|---|
K의 일원으로 | 클래스 외부 정의 | |||
추가 | a + b | R K::operator +(S b); | R operator +(K a, S b); | |
뺄셈 | a - b | R K::operator -(S b); | R operator -(K a, S b); | |
유니얼 플러스(정수 프로모션) | +a | R K::operator +(); | R operator +(K a); | |
단차 마이너스(가산 역수) | -a | R K::operator -(); | R operator -(K a); | |
곱셈 | a * b | R K::operator *(S b); | R operator *(K a, S b); | |
나누기 | a / b | R K::operator /(S b); | R operator /(K a, S b); | |
모듈로(정수 나머지)[a] | a % b | R K::operator %(S b); | R operator %(K a, S b); | |
증량 | 접두어 | ++a | R& K::operator ++(); | R& operator ++(K& a); |
포스트픽스 | a++ | R K::operator ++(int); | R operator ++(K& a, int); | |
참고: C++는 이름 없는 더미 매개 변수를 사용합니다. int 접두사와 후고정 증분 연산자를 구별합니다. | ||||
감소 | 접두어 | --a | R& K::operator --(); | R& operator --(K& a); |
포스트픽스 | a-- | R K::operator --(int); | R operator --(K& a, int); | |
참고: C++는 이름 없는 더미 매개 변수를 사용합니다. int 접두사와 후고정 감소 연산자를 구별합니다. |
비교 연산자/관계 연산자
모든 비교 연산자는 C++에서 과부하가 가능합니다. C++20 이므로 부등식 연산자는 다음과 같이 자동으로 생성됩니다. operator==
는 정의되며 4개의 관계 연산자 모두가 자동으로 생성됩니다. operator<=>
정의되어 있습니다.[1]
작업자명 | 구문 | 포함된 다에 | 프로토타입 예제 | ||
---|---|---|---|---|---|
K의 일원으로 | 클래스 외부 정의 | ||||
동등한 | a == b | 네. | bool K::operator ==(S const& b) const; | bool operator ==(K const& a, S const& b); | |
동일하지 않음 | a != b a not_eq b [b] | 네. | bool K::operator !=(S const& b) const; | bool operator !=(K const& a, S const& b); | |
보다 큼 | a > b | 네. | bool K::operator >(S const& b) const; | bool operator >(K const& a, S const& b); | |
보다 적은 | a < b | 네. | bool K::operator <(S const& b) const; | bool operator <(K const& a, S const& b); | |
크거나 같음 | a >= b | 네. | bool K::operator >=(S const& b) const; | bool operator >=(K const& a, S const& b); | |
이하 | a <= b | 네. | bool K::operator <=(S const& b) const; | bool operator <=(K const& a, S const& b); | |
삼원비교[c] | a <=> b | 아니요. | auto K::operator <=>(const S &b); | auto operator <=>(const K &a, const S &b); | |
연산자에는 총 3가지 반환 유형이 있습니다. std::weak_ordering , std::strong_ordering 그리고. std::partial_ordering 그들 모두가 전환할 수 있는 곳으로. |
논리 연산자
모든 논리 연산자는 C와 C++에 존재하며 C++에서 과부하될 수 있지만 논리 AND와 논리 OR의 과부하는 방지됩니다. 왜냐하면 과부하 연산자는 일반 함수 호출처럼 동작하기 때문에 두 연산자 모두 평가되므로 잘 사용되고 예상되는 단락 평가 속성을 잃게 됩니다.[2]
작업자명 | 구문 | C++ 시제품 예제 | ||
---|---|---|---|---|
K의 일원으로 | 클래스 외부 정의 | |||
논리적 부정(NOT) | !a not a [b] | bool K::operator !(); | bool operator !(K a); | |
논리 AND | a && b a and b [b] | bool K::operator &&(S b); | bool operator &&(K a, S b); | |
논리적 논리적 논리적 논리적 논리 | a b a ??!??! b [d][e]a or b [b] | bool K::operator (S b); | bool operator (K a, S b); |
비트와이즈 연산자
모든 비트와이즈 연산자는 C와 C++에 존재하며 C++에서 과부하가 가능합니다.
작업자명 | 구문 | 프로토타입 예제 | ||
---|---|---|---|---|
K의 일원으로 | 클래스 외부 정의 | |||
비트와이즈 NOT | ~a ??-a [d]compl a [b] | R K::operator ~(); | R operator ~(K a); | |
비트 와이즈 AND | a & b a bitand b [b] | R K::operator &(S b); | R operator &(K a, S b); | |
비트 와이즈 OR | a b a ??! b [d]a bitor b [b] | R K::operator (S b); | R operator (K a, S b); | |
비트와이즈 XOR | a ^ b a ??' b [d]a xor b [b] | R K::operator ^(S b); | R operator ^(K a, S b); | |
비트와이즈 왼쪽 시프트[f] | a << b | R K::operator <<(S b); | R operator <<(K a, S b); | |
비트와이즈 우 이동[f][g] | a >> b | R K::operator >>(S b); | R operator >>(K a, S b); |
할당 연산자
모든 할당식은 C와 C++로 존재하며 C++로 오버로드할 수 있습니다.
주어진 연산자에 대해 기본 제공된 결합된 할당 표현식의 의미론 a ⊚= b
다음과 같습니다. a = a ⊚ b
, 그것을 제외하고는 a
한 번만 평가됩니다.
작업자명 | 구문 | C++ 시제품 예제 | |
---|---|---|---|
K의 일원으로 | 클래스 외부 정의 | ||
직접할당 | a = b | R& K::operator =(S b); | — |
추가할당 | a += b | R& K::operator +=(S b); | R& operator +=(K& a, S b); |
감산할당 | a -= b | R& K::operator -=(S b); | R& operator -=(K& a, S b); |
곱셈배정 | a *= b | R& K::operator *=(S b); | R& operator *=(K& a, S b); |
사업부배정 | a /= b | R& K::operator /=(S b); | R& operator /=(K& a, S b); |
모듈로배정 | a %= b | R& K::operator %=(S b); | R& operator %=(K& a, S b); |
비트와이즈 및 할당 | a &= b a and_eq b [b] | R& K::operator &=(S b); | R& operator &=(K& a, S b); |
비트 단위 OR 할당 | a = b a ??!= b [d]a or_eq b [b] | R& K::operator =(S b); | R& operator =(K& a, S b); |
비트와이즈 XOR 할당 | a ^= b a ??'= b [d]a xor_eq b [b] | R& K::operator ^=(S b); | R& operator ^=(K& a, S b); |
비트 단위 왼쪽 시프트 할당 | a <<= b | R& K::operator <<=(S b); | R& operator <<=(K& a, S b); |
비트 단위 오른쪽 시프트 할당[g] | a >>= b | R& K::operator >>=(S b); | R& operator >>=(K& a, S b); |
멤버 및 포인터 연산자
작업자명 | 구문 | C++에서 과부하 가능 | 포함된 다에 | C++ 시제품 예제 | ||
---|---|---|---|---|---|---|
K의 일원으로 | 클래스 외부 정의 | |||||
첨자 | a[b] a<:b:> a??(b??) [d][h] | 네. | 네. | R& K::operator [](S b); R& K::operator [](S b, ...); // since C++23 | — | |
방향("a"로 가리킨 객체) | *a | 네. | 네. | R& K::operator *(); | R& operator *(K a); | |
주소-("a"의 주소) | &a bitand a [b][i] | 네[j] | 네. | R* K::operator &(); | R* operator &(K a); | |
구조 참조 해제("a"로 가리킨 개체의 멤버 b) | a->b | 네. | 네. | R* K::operator ->(); [k] | — | |
구조 참조("객체 a의 멤버 b") | a.b | 아니요. | 네. | — | ||
a가[l] 가리키는 객체의 포인터 대 멤버 b에 의해 선택된 멤버 | a->*b | 네. | 아니요. | R& K::operator ->*(S b); | R& operator ->*(K a, S b); | |
포인터 대 멤버 b에 의해 선택된 개체 a의 멤버 | a.*b | 아니요. | 아니요. | — |
기타 연산자
작업자명 | 구문 | C++에서 과부하 가능 | 포함된 다에 | 프로토타입 예제 | ||
---|---|---|---|---|---|---|
K의 일원으로 | 클래스 외부 정의 | |||||
함수호출 함수 개체를 참조하십시오. | a(a1, a2) | 네. | 네. | R K::operator ()(S a, T b, ...); | — | |
쉼표 | a, b | 네. | 네. | R K::operator ,(S b); | R operator ,(K a, S b); | |
3항 조건 | a ? b : c | 아니요. | 네. | — | ||
스코프 해상도 | a::b | 아니요. | 아니요. | — | ||
사용자 정의 리터럴[m] C++11 이후로 | "a"_b | 네. | 아니요. | — | R operator "" _b(T a) | |
의 크기 | sizeof a [n]sizeof (R) | 아니요. | 네. | — | ||
파라미터 팩의 크기 C++11 이후로 | sizeof...(Args) | 아니요. | 아니요. | — | ||
정렬의 C++11 이후로 | alignof(R) 아니면 _Alignof(R) [o] | 아니요. | 네. | — | ||
의 종류 C23년 이래로 | typeof (a) typeof (R) typeof_unqual (a) typeof_unqual (R) | — | 온리[p] | — | ||
데클타입 C++11 이후로 | decltype (a) decltype (R) | 아니요. | 아니요. | — | ||
유형식별 | typeid(a) typeid(R) | 아니요. | 아니요. | — | ||
컨버젼(C스타일 캐스트) | (R)a | 네. | 네. | K::operator R(); [4] | — | |
변환 | R(a) R{a} C++11 이후로auto(a) C++23 이후로auto{a} C++23 이후로 | 아니요. | 아니요. | 참고: const_cast/static_cast/reinterpret_cast처럼 동작합니다. 마지막 두 경우에는 auto 지정자는 다음과 같이 선언된 발명 변수 x의 유형으로 대체됩니다. auto x(a); (기능 선언으로 해석되지 않음) 또는 auto x{a}; , 각각 | ||
static_cast 변환 | static_cast<R>(a) | 네. | 아니요. | K::operator R(); explicit K::operator R(); C++11 이후로 | — | |
참고: 사용자 정의 변환의 경우 반환 형식은 형식을 추론하지 않는 한 암묵적으로 그리고 반드시 연산자 이름과 일치합니다(예: operator auto() , operator decltype(auto)() 등). | ||||||
동적 주조 변환 | dynamic_cast<R>(a) | 아니요. | 아니요. | — | ||
const_cast 변환 | const_cast<R>(a) | 아니요. | 아니요. | — | ||
재해석_캐스팅 변환 | reinterpret_cast<R>(a) | 아니요. | 아니요. | — | ||
스토리지 할당 | new R [q] | 네. | 아니요. | void* K::operator new(size_t x); | void* operator new(size_t x); | |
스토리지(어레이) 할당 | new R[n] new R<:n:> new R??(n??) [d][h][r] | 네. | 아니요. | void* K::operator new[](size_t a); | void* operator new[](size_t a); | |
스토리지 할당 해제 | delete a | 네. | 아니요. | void K::operator delete(void* a); | void operator delete(void* a); | |
스토리지(어레이) 할당 해제 | delete[] a delete<::> a delete??(??) a [d][h] | 네. | 아니요. | void K::operator delete[](void* a); | void operator delete[](void* a); | |
예외조회 C++11 이후로 | noexcept(a) | 아니요. | 아니요. | — |
주의:
- ^ 모듈러스 연산자는 정수 피연산자에서만 작동하므로 부동 소수점 수의 경우 라이브러리 함수를 대신 사용해야 합니다(예: ).
- ^ a b c d e f g h i j k l 필수
iso646.h
C. C++ 연산자 동의어 참조 - ^ C++20 삼원비교 정보
- ^ a b c d e f g h i 삼각형은 C++17에서 제거되었습니다. 그들은 C17 현재 C에서 여전히 사용할 수 있지만 C23에서는 제거될 것입니다.
- ^ 삼각형은 단순히 전처리기에 의해 대체되므로, 이 연산자에 있는 문자들의 다른 표현들은 어떤 방식으로든 혼합되고 매칭될 수 있습니다. 간결성을 위해 삼각형만 사용하고 둘 다 사용하지 않는 양식만 제공됩니다.
- ^ a b C++의 iostreams 맥락에서 작가들은 종종 다음을 언급할 것입니다.
<<
그리고.>>
각각 "put-to" 또는 "stream insertion"과 "get-from" 또는 "stream extraction" 연산자로 지정됩니다. - ^ a b C99 표준에 따르면 음수의 오른쪽 이동은 구현으로 정의됩니다. 예를 들어, GCC와 같은 대부분의 구현들은 산술적인 시프트(즉, 부호 확장)[3]를 사용하지만, 논리적인 시프트는 가능합니다.
- ^ a b c 삼각형 대괄호가 전처리기로 대체되고 다이어그램 대괄호가 동등한 대체 토큰이므로 대괄호는 일치할 필요가 없습니다. 다른 양식은 제공된 양식에서 쉽게 도출할 수 있으므로 괄호가 일치하는 경우만 포함됩니다.
- ^ 이 대체 형식은 C++ 연산자 동의어에 설명된 이유로 비트와이즈 및 대체 형식의 부작용입니다.
- ^ 오버로드된 개체의 실제 주소
operator &
로 얻을 수 있습니다. - ^ 반환 유형
operator->()
다음과 같은 유형이어야 합니다.->
포인터 타입과 같은 조작을 적용할 수 있습니다. 만약x
활자의C
어디에C
과중한 일operator->()
,x->y
로 확장됩니다.x.operator->()->y
. - ^ Meyers, Scott (October 1999), "Implementing operator->* for Smart Pointers" (PDF), Dr. Dobb's Journal, Aristeia.
- ^ C++11 사용자 정의 리터럴 정보
- ^ 괄호는 값의 크기를 취할 때는 필요하지 않으며, 형식의 크기를 취할 때만 사용할 수 있습니다. 그러나 일반적으로 상관없이 사용됩니다.
- ^ C++ 정의
alignof
연산자인 반면, C는 다음을 정의합니다._Alignof
(C23은 둘 다 정의합니다). 두 연산자의 의미는 동일합니다. - ^ C++23 기준,
typeof
그리고.typeof_unqual
언어의 일부가 아닙니다. - ^ 유형 이름도 유추할 수 있습니다(예:
new auto
) 초기화기가 제공되는 경우. - ^ 초기화기가 제공되는 경우 배열 크기를 유추할 수도 있습니다.
사업자우선순위
다음은 C와 C++ 언어의 모든 연산자의 우선순위와 연관성을 나열한 표입니다. 연산자는 내림차순으로 위에서 아래로 나열됩니다. 내림차순 우선순위는 연산자 및 피연산자 그룹의 우선순위를 나타냅니다. 식을 고려할 때 일부 행에 나열된 연산자는 그 아래 행에 나열된 연산자보다 먼저 그룹화됩니다. 동일한 셀에 있는 연산자(셀에 나열된 연산자 행이 여러 개 있을 수 있음)는 주어진 방향에서 동일한 우선 순위로 그룹화됩니다. 작업자의 우선 순위는 과부하에 영향을 받지 않습니다.
C와 C++의 표현 구문은 구 구조 문법에 의해 지정됩니다.[6] 여기 주어진 표는 문법에서 유추한 것입니다.[citation needed] ISO C 1999 표준의 경우, 섹션 6.5.6 주 71은 규격에 의해 제공되는 C 문법이 C 연산자의 우선순위를 정의한다고 명시하고 있으며, 또한 문법으로 인한 연산자 우선순위는 규격의 섹션 순서에 밀접하게 따른다고 명시하고 있습니다.
"[C] 구문 [즉, 문법]은 표현의 평가에 있어서 연산자의 우선순위를 명시하고 있는데, 이는 이 하위 절의 주요 하위 절의 순서, 가장 높은 우선순위와 같습니다."[7]
우선 순위 표는 대부분 적절하지만 몇 가지 세부 사항을 해결할 수 없습니다. 특히 3진 연산자는 할당 및 쉼표 연산자보다 우선 순위가 높은 것으로 나열됨에도 불구하고 임의의 표현을 중간 연산자로 허용합니다. 따라서 a ? b, c : d
로 해석됩니다. a ? (b, c) : d
, 무의미한 것처럼 (a ? b), (c : d)
. 따라서 조건 연산자의 중간에 있는 표현식(사이) ?
그리고. :
)는 괄호를 친 것처럼 구문 분석됩니다. 또한 C 캐스트 식의 즉각적인 비분리 결과는 다음 연산자가 될 수 없음을 유의하십시오. sizeof
.그러므로, sizeof (int) * x
로 해석됩니다. (sizeof(int)) * x
아닌 sizeof ((int) * x)
.
우선순위 | 교환입니다. | 묘사 | 연합성 |
---|---|---|---|
1 가장 높은 | :: | 스코프 해상도(C++만 해당) | 없음. |
2 | ++ | 후고정증분 | 왼쪽에서 오른쪽으로 |
-- | 후고정감소 | ||
() | 함수호출 | ||
[] | 배열 첨자 | ||
. | 참조에 의한 요소선택 | ||
-> | 포인터를 통한 요소 선택 | ||
typeid() | 런타임 유형 정보(C++만 해당)(typeid 참조) | ||
const_cast | 타입 캐스트 (C++만 해당) (const_cast 참조) | ||
dynamic_cast | 타입 캐스트 (C++만 해당) (동적 캐스트 참조) | ||
reinterpret_cast | 타입 캐스트 (C++만 해당) (reemplit_cast 참조) | ||
static_cast | 타입 캐스트 (C++만 해당) (static_cast 참조) | ||
3 | ++ | 접두어 증분 | 오른쪽에서 왼쪽으로 |
-- | 접두어 감소 | ||
+ | 일진법 | ||
- | 1차 마이너스 | ||
! | 논리적 없음 | ||
~ | 비트와이즈 NOT(보충) | ||
(type) | 활자주조 | ||
* | 방향(참조 해제) | ||
& | 주소지 | ||
sizeof | 의 크기 | ||
_Alignof | 정렬 요구사항(C11 이후) | ||
new , new[] | 동적 메모리 할당(C++만 해당) | ||
delete , delete[] | 동적 메모리 할당 해제(C++만 해당) | ||
4 | .* | 멤버에 대한 포인터(C++만 해당) | 왼쪽에서 오른쪽으로 |
->* | 멤버에 대한 포인터(C++만 해당) | ||
5 | * | 곱셈 | 왼쪽에서 오른쪽으로 |
/ | 나누기 | ||
% | 모듈로(잔여) | ||
6 | + | 추가 | 왼쪽에서 오른쪽으로 |
- | 뺄셈 | ||
7 | << | 비트와이즈 왼쪽 시프트 | 왼쪽에서 오른쪽으로 |
>> | 비트와이즈 우 이동 | ||
8 | <=> | 삼원비교(C++20 - C++에서만 도입) | 왼쪽에서 오른쪽으로 |
9 | < | 보다 적은 | 왼쪽에서 오른쪽으로 |
<= | 이하 | ||
> | 보다 큼 | ||
>= | 크거나 같음 | ||
10 | == | 동등한 | 왼쪽에서 오른쪽으로 |
!= | 동일하지 않음 | ||
11 | & | 비트 와이즈 AND | 왼쪽에서 오른쪽으로 |
12 | ^ | 비트와이즈 XOR(전용 또는 ) | 왼쪽에서 오른쪽으로 |
13 | | 비트와이즈 OR(포함 또는 포함) | 왼쪽에서 오른쪽으로 |
14 | && | 논리 AND | 왼쪽에서 오른쪽으로 |
15 | | 논리적 논리적 논리적 논리적 논리 | 왼쪽에서 오른쪽으로 |
16 | co_await | 코루틴 가공(C++만 해당) | 오른쪽에서 왼쪽으로 |
co_yield | |||
17 | ?: | 3차 조건 연산자 | 오른쪽에서 왼쪽으로 |
= | 직접할당 | ||
+= | 합계별할당 | ||
-= | 차등할당 | ||
*= | 제품별할당 | ||
/= | 몫별할당 | ||
%= | 나머지별할당 | ||
<<= | 비트 단위 왼쪽 시프트에 의한 할당 | ||
>>= | 비트 단위 오른쪽 시프트에 의한 할당 | ||
&= | 비트 단위 AND별 할당 | ||
^= | 비트 단위 XOR에 의한 할당 | ||
= | 비트 단위 OR에 의한 할당 | ||
throw | 던지기 조작자(던지기 예외, C++만 해당) | ||
18 최하의 | , | 쉼표 | 왼쪽에서 오른쪽으로 |
메모들
괄호로 명시적으로 지정되지 않은 경우, 선행 표는 연결된 표현식의 바인딩 순서를 결정합니다.
- 예를들면,
++x*3
일부 선행 규칙이 없으면 애매합니다. 우선 순위 표는 다음과 같습니다. x는 *보다 ++에 더 단단히 '결합'되어 있어, ++가 하는 일(지금 또는 나중, 아래 참조)은 x에만 해당합니다.x*3
); 다음과 같습니다.++x
,x*3
). - 마찬가지로, 다음과 같이.
3*x++
, 전체 식을 평가한 후에 사후 수정 ++가 작동하도록 설계된 경우, 우선 순위 표는 x만 증가하고 x는 증가하지 않음을 분명히 합니다.3*x
). 실제로 ( )라는 표현이tmp=x++
,3*tmp
)는 tmp를 임시 값으로 사용하여 평가됩니다. 기능적으로 다음과 같은 것과 같습니다.tmp=3*x
,++x
,tmp
).
- 우선순위나 구속력의 문제를 추상화하여 3+2*y[i]+라는 표현에 대해 위 도표를 고려합니다. 컴파일러의 작업은 다이어그램을 여러 단항 연산자(3+(..), 2*(..), ( . )+, ( . )[ i ])가 y에 바인딩하기 위해 경쟁하는 식으로 해결하는 것입니다. 우선 순위 표는 각 사용자가 수행하는 최종 하위 표현식을 해결합니다. ( . )[ i ]는 y에만 작용하고 ( . )+는 y[i]에만 작용하며, 2*( . )는 y[i]+에만 작용하고 3+( . )는 2*(y[i]+)에 '만' 작용합니다. 각 연산자가 수행하는 하위 표현식이 수행되는 것은 우선 순위 테이블에서 명확하지만 각 연산자가 수행하는 작업이 수행되는 경우는 우선 순위 테이블로 해결되지 않습니다. 이 예에서 ( . )++ 연산자는 우선 순위 규칙에 의해 y[i]에만 수행하지만 바인딩 수준만으로는 후위 고정 ++( )의 타이밍을 나타내지 않습니다. )++ 연산자는 y[i]가 식에서 평가된 후에만 동작합니다.
다중 문자 시퀀스를 포함하는 연산자 중 다수에는 각 문자의 연산자 이름에서 구축된 "이름"이 부여됩니다. 예를들면, +=
그리고. -=
흔히 "더하기에 의한 assign"와 "감산에 의한 assign" 대신에 "더하기에 의한 assign"와 "더하기에 의한 등호"라고 불립니다. C와 C++의 연산자 바인딩은 (해당 표준에서) 우선 순위 표가 아닌 인수분해 언어 문법으로 지정됩니다. 이것은 약간의 미묘한 갈등을 만듭니다. 예를 들어 C에서 조건식의 구문은 다음과 같습니다.
이치에 맞는-오어-표현 ? 표현 : 조건부의-표현
C++에 있을 때는 다음과 같습니다.
이치에 맞는-오어-표현 ? 표현 : 과제-표현
따라서 다음과 같은 표현이 있습니다.
e = a < d ? a++ : a = d
두 언어에서 구문 분석이 다릅니다. C에서 할당식의 구문은 다음과 같으므로 C에서 이 식은 구문 오류입니다.
일의의-표현 '=' 과제-표현
C++에서는 다음과 같이 파싱됩니다.
e = (a < d ? a++ : (a = d))
단일 함수 인수, 변수 할당 또는 기타 쉼표로 구분된 목록 내에서 쉼표를 연산자로 사용하려면 [13][14]다음과 같이 괄호를 사용해야 합니다.
인트의 a = 1, b = 2, 이상한 변수 = (++a, b), d = 4;
비트 와이즈 및 평등 연산자 우선 순위에 대한 비판
비트와이즈 논리 연산자의 우선순위에 대한 비판이 있었습니다.[15] 개념적으로 &는 *와 +와 같은 산술 연산자입니다.
표정이. a & b == 7
구문적으로 다음과 같이 구문 분석됩니다. a & (b == 7)
반면에 표현은 a + b == 7
로 해석됩니다. (a + b) == 7
. 이를 위해서는 괄호를 그렇지 않은 경우보다 더 자주 사용해야 합니다.
역사적으로 비트와이즈 연산자와 논리 연산자 사이에는 구문론적인 구분이 없었습니다. BCPL, B 및 초기 C에서는 연산자가 &&
존재하지 않았습니다. 대신 &
이들이 'truth-value context'에서 사용되는지 여부에 따라 다른 의미를 갖습니다(예를 들어, 부울 값이 예상되는 경우). if (a==b & c) {...}
논리 연산자로 작동했지만, 다음과 같은 경우. c = a & b
그것은 약간 현명한 것으로 행동했습니다). 기존 설치와 하위 호환성을 유지하기 위해 유지되었습니다.[16]
또한 C++(및 이후 버전의 C) 동등성 연산에서는 삼원 비교 연산자를 제외하고는 개념적으로 단일 비트(1 또는 0)이므로 "비트와이즈" 연산에 적절하게 속하지 않는 보울 유형 값을 산출합니다.
C++ 연산자 동의어
C++는 특정 키워드를 정의하여[17] 여러 연산자의 별칭으로 사용합니다.
키워드 | 교환입니다. |
---|---|
and | && |
and_eq | &= |
bitand | & |
bitor | |
compl | ~ |
not | ! |
not_eq | != |
or | |
or_eq | = |
xor | ^ |
xor_eq | ^= |
이들은 다른 이름으로 동일한 연산자가 아니라 각 연산자의 이름(문자열)에 대한 단순한 토큰 대체이기 때문에 대체하는 문장 부호와 정확히 동일한 방식으로 사용할 수 있습니다. 이것은 그 표현들이 (a > 0 and not flag)
그리고. (a > 0 && !flag)
뜻이 같습니다 예를 들어, 다음과 같은 의미이기도 합니다. bitand
키워드는 비트와이즈 연산자뿐만 아니라 주소 연산자를 대체하는 데 사용될 수 있으며, 참조 유형을 지정하는 데에도 사용될 수 있습니다(예: int bitand ref = n
). ISO C 사양은 헤더 파일의 전처리 매크로로서 이러한 키워드를 허용합니다. C와의 호환성을 위해 C++는 헤더를 제공하며 포함해도 효과가 없습니다.
참고 항목
참고문헌
- ^ "Operator overloading§Comparison operators". cppreference.com.
- ^ "Standard C++".
- ^ "Integers implementation", GCC 4.3.3, GNU.
- ^ "user-defined conversion". Retrieved 5 April 2020.
- ^ C++의 명시적 유형 변환
- ^ ISO/IEC 9899:201x Programming Languages - C. open-std.org – The C Standards Committee. 19 December 2011. p. 465.
- ^ the ISO C 1999 standard, section 6.5.6 note 71 (Technical report). ISO. 1999.
- ^ "C Operator Precedence - cppreference.com". en.cppreference.com. Retrieved 16 July 2019.
- ^ "C++ Built-in Operators, Precedence and Associativity". docs.microsoft.com. Retrieved 11 May 2020.
- ^ "C++ Operator Precedence - cppreference.com". en.cppreference.com. Retrieved 16 July 2019.
- ^ "C Operator Precedence - cppreference.com". en.cppreference.com. Retrieved 10 April 2020.
- ^ "Does the C/C++ ternary operator actually have the same precedence as assignment operators?". Stack Overflow. Retrieved 22 September 2019.
- ^ "Other operators - cppreference.com". en.cppreference.com. Retrieved 10 April 2020.
- ^ "c++ - How does the Comma Operator work". Stack Overflow. Retrieved 1 April 2020.
- ^ C history § Neonatal C, Bell labs.
- ^ "Re^10: next unless condition". www.perlmonks.org. Retrieved 23 March 2018.
- ^ ISO/IEC 14882:1998(E) Programming Language C++. open-std.org – The C++ Standards Committee. 1 September 1998. pp. 40–41.
외부 링크
- "Operators", C++ reference (wiki).
- C 연산자 우선 순위
- Postfix Increment and Decrement Operators: ++ and -- (Developer network), Microsoft, 17 August 2021.