From Wikipedia, the free encyclopedia
List of operators in C and C++
This is a list of operators in the C and C++ programming languages.
All listed operators are in C++ and lacking indication otherwise, in C as well. Some tables include a "In C" column that indicates whether an operator is also in C. Note that C does not support operator overloading.
When not overloaded, for the operators &&
, ||
, and ,
(the comma operator), there is a sequence point after the evaluation of the first operand.
Most of the operators available in C and C++ are also available in other C-family languages such as C#, D, Java, Perl, and PHP with the same precedence, associativity, and semantics.
Many operators specified by a sequence of symbols are commonly referred to by a name that consists of the name of each symbol. For example, +=
and -=
are often called "plus equal(s)" and "minus equal(s)", instead of the more verbose "assignment by addition" and "assignment by subtraction".
In the following tables, lower case letters such as a
and b
represent literal values, object/variable names, or l-values, as appropriate. R
, S
and T
stand for a data type, and K
for a class or enumeration type. Some operators have alternative spellings using digraphs and trigraphs or operator synonyms.
C and C++ have the same arithmetic operators and all can be overloaded in C++.
Operation Syntax C++ prototype in class K outside class Additiona + b
R K::operator +(S b);
R operator +(K a, S b);
Subtraction a - b
R K::operator -(S b);
R operator -(K a, S b);
Unary plus; integer promotion +a
R K::operator +();
R operator +(K a);
Unary minus; additive inverse -a
R K::operator -();
R operator -(K a);
Multiplication a * b
R K::operator *(S b);
R operator *(K a, S b);
Division a / b
R K::operator /(S b);
R operator /(K a, S b);
Modulo[a] a % b
R K::operator %(S b);
R operator %(K a, S b);
Prefix increment ++a
R& K::operator ++();
R& operator ++(K& a);
Postfix increment a++
R K::operator ++(int);
[b] R operator ++(K& a, int);
[b] Prefix decrement --a
R& K::operator --();
R& operator --(K& a);
Postfix decrement a--
R K::operator --(int);
[b] R operator --(K& a, int);
[b]
All relational (comparison) operators can be overloaded in C++. Since C++20, the inequality operator is automatically generated if operator==
is defined and all four relational operators are automatically generated if operator<=>
is defined.[1]
a == b
Yes bool K::operator ==(S const& b) const;
bool operator ==(K const& a, S const& b);
Not equal to a != b
Yes bool K::operator !=(S const& b) const;
bool operator !=(K const& a, S const& b);
Greater than a > b
Yes bool K::operator >(S const& b) const;
bool operator >(K const& a, S const& b);
Less than a < b
Yes bool K::operator <(S const& b) const;
bool operator <(K const& a, S const& b);
Greater than or equal to a >= b
Yes bool K::operator >=(S const& b) const;
bool operator >=(K const& a, S const& b);
Less than or equal to a <= b
Yes bool K::operator <=(S const& b) const;
bool operator <=(K const& a, S const& b);
Three-way comparison[c][d] a <=> b
No auto K::operator <=>(const S &b);
auto operator <=>(const K &a, const S &b);
C and C++ have the same logical operators and all can be overloaded in C++.
Note that overloading logical AND and OR is discouraged, because as overloaded operators they always evaluate both operands instead of providing the normal semantics of short-circuit evaluation.[2]
Operation Syntax C++ prototype in class K outside class NOT!a
bool K::operator !();
bool operator !(K a);
AND a && b
bool K::operator &&(S b);
bool operator &&(K a, S b);
OR a || b
bool K::operator ||(S b);
bool operator ||(K a, S b);
C and C++ have the same bitwise operators and all can be overloaded in C++.
Operation Syntax C++ prototype in class K outside class NOT~a
R K::operator ~();
R operator ~(K a);
AND a & b
R K::operator &(S b);
R operator &(K a, S b);
OR a | b
R K::operator |(S b);
R operator |(K a, S b);
XOR a ^ b
R K::operator ^(S b);
R operator ^(K a, S b);
Shift left[e] a << b
R K::operator <<(S b);
R operator <<(K a, S b);
Shift right[e][f] a >> b
R K::operator >>(S b);
R operator >>(K a, S b);
C and C++ have the same assignment operators and all can be overloaded in C++.
For the combination operators, a ⊚= b
(where ⊚
represents an operation) is equivalent to a = a ⊚ b
, except that a
is evaluated only once.
a = b
R& K::operator =(S b);
— Addition combination a += b
R& K::operator +=(S b);
R& operator +=(K& a, S b);
Subtraction combination a -= b
R& K::operator -=(S b);
R& operator -=(K& a, S b);
Multiplication combination a *= b
R& K::operator *=(S b);
R& operator *=(K& a, S b);
Division combination a /= b
R& K::operator /=(S b);
R& operator /=(K& a, S b);
Modulo combination a %= b
R& K::operator %=(S b);
R& operator %=(K& a, S b);
Bitwise AND combination a &= b
R& K::operator &=(S b);
R& operator &=(K& a, S b);
Bitwise OR combination a |= b
R& K::operator |=(S b);
R& operator |=(K& a, S b);
Bitwise XOR combination a ^= b
R& K::operator ^=(S b);
R& operator ^=(K& a, S b);
Bitwise left shift combination a <<= b
R& K::operator <<=(S b);
R& operator <<=(K& a, S b);
Bitwise right shift combination[g] a >>= b
R& K::operator >>=(S b);
R& operator >>=(K& a, S b);
Member and pointer[edit] Operation Syntax Can overload In C C++ prototype in class K outside class Subscript a[b]
a<:b:>
[4] Yes Yes R& K::operator [](S b);
R& K::operator [](S b, ...);
[h] — Indirection
*a
Yes Yes R& K::operator *();
R& operator *(K a);
Address-of
&a
Yes[i] Yes R* K::operator &();
R* operator &(K a);
Structure dereference
a->b
Yes Yes R* K::operator ->();
[j]
a.b
No Yes — Member selected by pointer-to-member b of object pointed to by a[k] a->*b
Yes No R& K::operator ->*(S b);
R& operator ->*(K a, S b);
Member of object a selected by pointer-to-member b a.*b
No No — Operation Syntax Can overload In C C++ prototype in class K outside class Function call a(a1, a2)
Yes Yes R K::operator ()(S a, T b, ...);
— Comma a, b
Yes Yes R K::operator ,(S b);
R operator ,(K a, S b);
Ternary conditional a ? b : c
No Yes — Scope resolution a::b
[l] No No — User-defined literals[m][n] "a"_b
Yes No — R operator "" _b(T a)
Sizeof sizeof a
[o]
sizeof (R)
No Yes — Size of parameter pack[n] sizeof...(Args)
No No — Alignof[n] alignof(R)
_Alignof(R)
[p] No Yes — Decltype[n] decltype (a)
decltype (R)
No No — Type identification typeid(a)
typeid(R)
No No — Conversion
(R)a
Yes Yes K::operator R();
[5] — Conversion[q][6] R(a)
R{a}
[n]
auto(a)
[h]
auto{a}
[h] No No — static_cast conversion[r] static_cast<R>(a)
Yes No K::operator R();
explicit K::operator R();
[n] — dynamic cast conversion dynamic_cast<R>(a)
No No — const_cast conversion const_cast<R>(a)
No No — reinterpret_cast conversion reinterpret_cast<R>(a)
No No — Allocate storage new R
[s] Yes No void* K::operator new(size_t x);
void* operator new(size_t x);
Allocate array new R[n]
[t] Yes No void* K::operator new[](size_t a);
void* operator new[](size_t a);
Deallocate storage delete a
Yes No void K::operator delete(void* a);
void operator delete(void* a);
Deallocate array delete[] a
Yes No void K::operator delete[](void* a);
void operator delete[](void* a);
Exception check[n] noexcept(a)
No No —
C++ defines keywords to act as aliases for a number of operators:[7]
Keyword Operatorand
&&
and_eq
&=
bitand
&
bitor
|
compl
~
not
!
not_eq
!=
or
||
or_eq
|=
xor
^
xor_eq
^=
Each keyword is a different way to specify an operator and as such can be used instead of the corresponding symbolic variation. For example, (a > 0 and not flag)
and (a > 0 && !flag)
specify the same behavior. As another example, the bitand
keyword may be used to replace not only the bitwise-and operator but also the address-of operator, and it can be used to specify reference types (e.g., int bitand ref = n
).
The ISO C specification makes allowance for these keywords as preprocessor macros in the header file iso646.h
. For compatibility with C, C++ also provides the header iso646.h
, the inclusion of which has no effect. Until C++20, it also provided the corresponding header ciso646
which had no effect as well.
During expression evaluation, the order in which sub-expressions are evaluated is determined by precedence and associativity. An operator with higher precedence is evaluated before a operator of lower precedence and the operands of an operator are evaluated based on associativity. The following table describes the precedence and associativity of the C and C++ operators. Operators are shown in groups of equal precedence with groups ordered in descending precedence from top to bottom (lower order is higher precedence).[8][9][10]
Operator precedence is not affected by overloading.
Order Operator Description Associativity 1highest
::
Scope resolution (C++ only) None 2 ++
Postfix increment Left-to-right --
Postfix decrement ()
Function call []
Array subscripting .
Element selection by reference ->
Element selection through pointer typeid()
Run-time type information (C++ only) (see typeid) const_cast
Type cast (C++ only) (see const_cast) dynamic_cast
Type cast (C++ only) (see dynamic cast) reinterpret_cast
Type cast (C++ only) (see reinterpret_cast) static_cast
Type cast (C++ only) (see static_cast) 3 ++
Prefix increment Right-to-left --
Prefix decrement +
Unary plus -
Unary minus !
Logical NOT ~
Bitwise NOT (ones' complement) (type)
Type cast *
Indirection (dereference) &
Address-of sizeof
Sizeof _Alignof
Alignment requirement (since C11) new
, new[]
Dynamic memory allocation (C++ only) delete
, delete[]
Dynamic memory deallocation (C++ only) 4 .*
Pointer to member (C++ only) Left-to-right ->*
Pointer to member (C++ only) 5 *
Multiplication Left-to-right /
Division %
Modulo (remainder) 6 +
Addition Left-to-right -
Subtraction 7 <<
Bitwise left shift Left-to-right >>
Bitwise right shift 8 <=>
Three-way comparison (Introduced in C++20 - C++ only) Left-to-right 9 <
Less than Left-to-right <=
Less than or equal to >
Greater than >=
Greater than or equal to 10 ==
Equal to Left-to-right !=
Not equal to 11 &
Bitwise AND Left-to-right 12 ^
Bitwise XOR (exclusive or) Left-to-right 13 |
Bitwise OR (inclusive or) Left-to-right 14 &&
Logical AND Left-to-right 15 ||
Logical OR Left-to-right 16 co_await
Coroutine processing (C++ only) Right-to-left co_yield
17 ?:
Ternary conditional operator Right-to-left =
Direct assignment +=
Assignment by sum -=
Assignment by difference *=
Assignment by product /=
Assignment by quotient %=
Assignment by remainder <<=
Assignment by bitwise left shift >>=
Assignment by bitwise right shift &=
Assignment by bitwise AND ^=
Assignment by bitwise XOR |=
Assignment by bitwise OR throw
Throw operator (exceptions throwing, C++ only) 18
lowest
,
Comma Left-to-right
Although this table is adequate for describing most evaluation order, it does not describe a few details. The ternary operator allows any arbitrary expression as its middle operand, despite being listed as having higher precedence than the assignment and comma operators. Thus a ? b, c : d
is interpreted as a ? (b, c) : d
, and not as the meaningless (a ? b), (c : d)
. So, the expression in the middle of the conditional operator (between ?
and :
) is parsed as if parenthesized. Also, the immediate, un-parenthesized result of a C cast expression cannot be the operand of sizeof
. Therefore, sizeof (int) * x
is interpreted as (sizeof(int)) * x
and not sizeof ((int) * x)
.
The precedence table determines the order of binding in chained expressions, when it is not expressly specified by parentheses.
++x*3
is ambiguous without some precedence rule(s). The precedence table tells us that: x is 'bound' more tightly to ++ than to *, so that whatever ++ does (now or later—see below), it does it ONLY to x (and not to x*3
); it is equivalent to (++x
, x*3
).3*x++
, where though the post-fix ++ is designed to act AFTER the entire expression is evaluated, the precedence table makes it clear that ONLY x gets incremented (and NOT 3*x
). In fact, the expression (tmp=x++
, 3*tmp
) is evaluated with tmp being a temporary value. It is functionally equivalent to something like (tmp=3*x
, ++x
, tmp
).The binding of operators in C and C++ is specified by a factored language grammar, rather than a precedence table. This creates some subtle conflicts. For example, in C, the syntax for a conditional expression is:
logical-OR-expression ? expression : conditional-expression
while in C++ it is:
logical-OR-expression ? expression : assignment-expression
Hence, the expression:
is parsed differently in the two languages. In C, this expression is a syntax error, because the syntax for an assignment expression in C is:
unary-expression '=' assignment-expression
In C++, it is parsed as:
e = (a < d ? a++ : (a = d))
which is a valid expression.[11][12]
To use the comma operator in a function call argument expression, variable assignment, or a comma-separated list, use of parentheses is required.[13][14] For example,
int a = 1, b = 2, weirdVariable = (++a, b), d = 4;Criticism of bitwise and equality operators precedence[edit]
The precedence of the bitwise logical operators has been criticized.[15] Conceptually, & and | are arithmetic operators like * and +.
The expression a & b == 7
is syntactically parsed as a & (b == 7)
whereas the expression a + b == 7
is parsed as (a + b) == 7
. This requires parentheses to be used more often than they otherwise would.
Historically, there was no syntactic distinction between the bitwise and logical operators. In BCPL, B and early C, the operators && ||
didn't exist. Instead & |
had different meaning depending on whether they are used in a 'truth-value context' (i.e. when a Boolean value was expected, for example in if (a==b & c) {...}
it behaved as a logical operator, but in c = a & b
it behaved as a bitwise one). It was retained so as to keep backward compatibility with existing installations.[16]
Moreover, in C++ (and later versions of C) equality operations, with the exception of the three-way comparison operator, yield bool type values which are conceptually a single bit (1 or 0) and as such do not properly belong in "bitwise" operations.
fmod
can be used.int
is a dummy parameter to differentiate between prefix and postfix.std::weak_ordering
, std::strong_ordering
and std::partial_ordering
to which they all are convertible to.<<
and >>
as the "put-to" or "stream insertion" and "get-from" or "stream extraction" operators, respectively.operator &
can be obtained with std::addressof
operator->()
must be a type for which the ->
operation can be applied, such as a pointer type. If x
is of type C
where C
overloads operator->()
, x->y
gets expanded to x.operator->()->y
.::
punctuator exists in C as of C23, it is not used as a scope resolution operator.alignof
operator, whereas C defines _Alignof
(C23 defines both). Both operators have the same semantics.auto
specifier is replaced with the type of the invented variable x declared with auto x(a);
(which is never interpreted as a function declaration) or auto x{a};
, respectively.operator auto()
, operator decltype(auto)()
etc.).new auto
) if an initializer is provided.RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4