算术运算符
返回特定算术运算的结果。
运算符名称 | 语法 | 原型示例 (对于 class T) | ||
---|---|---|---|---|
在类定义内 | 在类定义外 | |||
一元加 | +a | T T::operator+() const; | T operator+(const T& a); | |
一元减 | -a | T T::operator-() const; | T operator-(const T& a); | |
加法 | a + b | T T::operator+(const T2& b) const; | T operator+(const T& a, const T2& b); | |
减法 | a - b | T T::operator-(const T2& b) const; | T operator-(const T& a, const T2& b); | |
乘法 | a * b | T T::operator*(const T2& b) const; | T operator*(const T& a, const T2& b); | |
除法 | a / b | T T::operator/(const T2& b) const; | T operator/(const T& a, const T2& b); | |
求余 | a % b | T T::operator%(const T2& b) const; | T operator%(const T& a, const T2& b); | |
按位非 | ~a | T T::operator~() const; | T operator~(const T& a); | |
按位与 | a & b | T T::operator&(const T2& b) const; | T operator&(const T& a, const T2& b); | |
按位或 | a | b | T T::operator|(const T2& b) const; | T operator|(const T& a, const T2& b); | |
按位异或 | a ^ b | T T::operator^(const T2& b) const; | T operator^(const T& a, const T2& b); | |
按位左移 | a << b | T T::operator<<(const T2& b) const; | T operator<<(const T& a, const T2& b); | |
按位右移 | a >> b | T T::operator>>(const T2& b) const; | T operator>>(const T& a, const T2& b); | |
|
目录 |
[编辑] 通用解释
所有内置算术运算符都计算特定算术运算的结果并返回其结果。参数不会被修改。
[编辑] 转换
如果传递给内置算术运算符的操作数是整型或无作用域枚举类型,则在任何其他操作之前(但在左值到右值转换之后,如果适用),操作数会经历整型提升。如果操作数具有数组或函数类型,则应用数组到指针和函数到指针转换。
对于二元运算符(移位运算符除外),如果提升后的操作数具有不同的类型,则应用常用算术转换。
[编辑] 溢出
无符号整数算术始终以 模 2n
执行,其中 n 是该特定整数中的位数。例如,对于 unsigned int,将 1 加到 UINT_MAX 得到 0,从 0 减去 1 得到 UINT_MAX。
当有符号整数算术运算溢出时(结果不适合结果类型),行为是未定义的,— 这种操作的可能表现形式包括
- 它根据表示规则(通常为补码)环绕,
- 它会陷入陷阱 — 在某些平台上或由于编译器选项(例如 GCC 和 Clang 中的
-ftrapv
), - 它会饱和到最小值或最大值(在许多 DSP 上),
- 它完全被编译器优化掉。
[编辑] 浮点环境
如果支持 #pragma STDC FENV_ACCESS 并设置为 ON
,则所有浮点算术运算符都遵守当前的浮点舍入方向,并按照 math_errhandling 中的规定报告浮点算术错误,除非是 静态初始化器 的一部分(在这种情况下,不会引发浮点异常,并且舍入模式为舍入到最接近的值)。
[编辑] 浮点收缩
除非支持 #pragma STDC FP_CONTRACT 并设置为 OFF
,否则所有浮点算术运算都可以执行,就好像中间结果具有无限范围和精度一样,即允许省略舍入误差和浮点异常的优化。例如,C++ 允许使用单个融合乘加 CPU 指令实现 (x * y) + z,或将 a = x * x * x * x; 优化为 tmp = x * x; a = tmp * tmp。
与收缩无关,浮点算术的中间结果可能具有与其类型指示的范围和精度不同的范围和精度,请参阅 FLT_EVAL_METHOD。
形式上,C++ 标准不保证浮点运算的精度。
[编辑] 一元算术运算符
一元算术运算符表达式具有以下形式
+ 表达式 |
(1) | ||||||||
- 表达式 |
(2) | ||||||||
一元 +
和 -
运算符的优先级高于所有二元算术运算符,因此 表达式 不能包含顶层二元算术运算符。这些运算符从右到左结合
+a - b; // equivalent to (+a) - b, NOT +(a - b) -c + d; // equivalent to (-c) + d, NOT -(c + d) +-e; // equivalent to +(-e), the unary + is a no-op if “e” is a built-in type // because any possible promotion is performed during negation already
[编辑] 内置一元算术运算符
-a,其中 N 是提升后的位数。
- 换句话说,结果是操作数的补码(其中操作数和结果都被视为无符号数)。
[编辑] 重载
在针对用户定义的运算符的重载解析中,对于每个 cv-非限定的提升算术类型 A
和每种类型 T
,以下函数签名参与重载解析
A operator+(A) |
||
T* operator+(T*) |
||
A operator-(A) |
||
#include <iostream> int main() { char c = 0x6a; int n1 = 1; unsigned char n2 = 1; unsigned int n3 = 1; std::cout << "char: " << c << " int: " << +c << "\n" "-1, where 1 is signed: " << -n1 << "\n" "-1, where 1 is unsigned char: " << -n2 << "\n" "-1, where 1 is unsigned int: " << -n3 << '\n'; char a[3]; std::cout << "size of array: " << sizeof a << "\n" "size of pointer: " << sizeof +a << '\n'; }
可能输出
char: j int: 106 -1, where 1 is signed: -1 -1, where 1 is unsigned char: -1 -1, where 1 is unsigned int: 4294967295 size of array: 3 size of pointer: 8
[编辑] 加法运算符
加法运算符表达式具有以下形式
左操作数 + 右操作数 |
(1) | ||||||||
左操作数 - 右操作数 |
(2) | ||||||||
二元 +
和 -
运算符的优先级高于除 *
、/
和 %
之外的所有其他二元算术运算符。这些运算符从左到右结合
a + b * c; // equivalent to a + (b * c), NOT (a + b) * c d / e - f; // equivalent to (d / e) - f, NOT d / (e - f) g + h >> i; // equivalent to (g + h) >> i, NOT g + (h >> i) j - k + l - m; // equivalent to ((j - k) + l) - m
[编辑] 内置加法运算符
对于内置二元加法和二元减法运算符,左操作数 和 右操作数 都必须是纯右值,并且必须满足以下条件之一
- 两个操作数都具有算术或无作用域枚举类型。在这种情况下,对两个操作数执行常用算术转换。
- 只有一个操作数具有整型或无作用域枚举类型。在这种情况下,对该操作数应用整型提升。
在本节的其余描述中,“操作数”、“左操作数”和“右操作数”指的是转换后或提升后的操作数。
- 两个操作数都具有算术类型。在这种情况下,结果是操作数的和。
- 一个操作数是指向完全定义的对象类型的指针,另一个操作数具有整型。在这种情况下,将整型值添加到指针(参见指针算术)。
如果两个操作数都具有浮点类型,并且该类型支持 IEEE 浮点算术(参见 std::numeric_limits::is_iec559)
- 如果一个操作数是 NaN,则结果为 NaN。
- 无穷减无穷是 NaN,并且会引发 FE_INVALID。
- 无穷加负无穷是 NaN,并且会引发 FE_INVALID。
[编辑] 指针算术
当将具有整型类型 的表达式 J 添加到指针类型表达式 P 或从中减去时,结果具有 P 的类型。
- 如果 P 的计算结果为空指针值,并且 J 的计算结果为 0,则结果为空指针值。
- 否则,如果 P 指向具有 n 个元素的数组对象 x 的第
i
个元素,给定 J 的值为 j,则 P 的加法或减法如下
- 表达式 P + J 和 J + P
- 指向
i+j
th element of x 如果 i + j 在[
0,
n)
范围内,并且 - 是指向 x 的最后一个元素之后的位置的指针,如果 i + j 是 n。
- 指向
- 表达式 P - J
- 指向
i-j
th element of x 如果 i - j 在[
0,
n)
范围内,并且 - 是指向 x 的最后一个元素之后的位置的指针,如果 i - j 是 n。
- 指向
- 其他 j 值会导致未定义行为。
- 否则,如果 P 指向一个完整的对象、一个基类子对象或一个成员子对象 y,给定 J 的值为 j,则 P 的加法或减法运算如下
- 表达式 P + J 和 J + P
- 指向 y 如果 j 是 0,并且
- 是指向 y 结尾之后的位置的指针,如果 j 是 1。
- 表达式 P - J
- 指向 y 如果 j 是 0,并且
- 是指向 y 结尾之后的位置的指针,如果 j 是 -1。
- 其他 j 值会导致未定义行为。
- 否则,如果 P 是指向对象 z 结尾之后的位置的指针,给定 J 的值为 j
- 如果 z 是具有 n 个元素的数组对象,则 P 的加法或减法运算如下
- 表达式 P + J 和 J + P
- 指向
n+j
th element of z 如果 n + j 在[
0,
n)
范围内,并且 - 是指向 z 的最后一个元素之后的位置的指针,如果 j 是 0。
- 指向
- 表达式 P - J
- 指向
n-j
th element of z 如果 n - j 在[
0,
n)
范围内,并且 - 是指向 z 的最后一个元素之后的位置的指针,如果 j 是 0。
- 指向
- 其他 j 值会导致未定义行为。
- 否则,P 的加法或减法运算如下
- 表达式 P + J 和 J + P
- 指向 z 如果 j 是 -1,并且
- 是指向 z 结尾之后的位置的指针,如果 j 是 0。
- 表达式 P - J
- 指向 z 如果 j 是 1,并且
- 是指向 z 结尾之后的位置的指针,如果 j 是 0。
- 其他 j 值会导致未定义行为。
- 否则,行为是未定义的。
当两个指针表达式 P 和 Q 相减时,结果的类型是 std::ptrdiff_t。
- 如果 P 和 Q 都求值为空指针值,则结果为 0。
- 否则,如果 P 和 Q 分别指向同一个数组对象 x 的第
i
个和第j
个数组元素,则表达式 P - Q 的值为 i − j。
- 如果 i − j 不能用 std::ptrdiff_t 表示,则行为是未定义的。
- 否则,如果 P 和 Q 指向同一个完整的对象、基类子对象或成员子对象,则结果为 0。
- 否则,行为是未定义的。
这些指针算术运算符允许指针满足 LegacyRandomAccessIterator 的要求。
对于加法和减法,如果 P 或 Q 具有类型 “pointer to (possibly cv-qualified) T
”,其中 T
和数组元素类型不是 相似的,则行为是未定义的
int arr[5] = {1, 2, 3, 4, 5}; unsigned int *p = reinterpret_cast<unsigned int*>(arr + 1); unsigned int k = *p; // OK, the value of “k” is 2 unsigned int *q = p + 1; // undefined behavior: “p” points to int, not unsigned int
[编辑] 重载
在 针对用户定义的运算符的重载决议中,对于每对提升的算术类型 L
和 R
以及对于每个对象类型 T
,以下函数签名参与重载决议
LR operator+(L, R) |
||
LR operator-(L, R) |
||
T* operator+(T*, std::ptrdiff_t) |
||
T* operator+(std::ptrdiff_t, T*) |
||
T* operator-(T*, std::ptrdiff_t) |
||
std::ptrdiff_t operator-(T*, T*) |
||
其中 LR
是 L
和 R
上 常用算术转换 的结果。
#include <iostream> int main() { char c = 2; unsigned int un = 2; int n = -10; std::cout << " 2 + (-10), where 2 is a char = " << c + n << "\n" " 2 + (-10), where 2 is unsigned = " << un + n << "\n" " -10 - 2.12 = " << n - 2.12 << '\n'; char a[4] = {'a', 'b', 'c', 'd'}; char* p = &a[1]; std::cout << "Pointer addition examples: " << *p << *(p + 2) << *(2 + p) << *(p - 1) << '\n'; char* p2 = &a[4]; std::cout << "Pointer difference: " << p2 - p << '\n'; }
输出
2 + (-10), where 2 is a char = -8 2 + (-10), where 2 is unsigned = 4294967288 -10 - 2.12 = -12.12 Pointer addition examples: bdda Pointer difference: 3
[编辑] 乘法运算符
乘法运算符表达式具有以下形式
lhs * rhs |
(1) | ||||||||
lhs / rhs |
(2) | ||||||||
lhs % rhs |
(3) | ||||||||
乘法运算符的优先级高于所有其他二元算术运算符。 这些运算符从左到右结合
a + b * c; // equivalent to a + (b * c), NOT (a + b) * c d / e - f; // equivalent to (d / e) - f, NOT d / (e - f) g % h >> i; // equivalent to (g % h) >> i, NOT g % (h >> i) j * k / l % m; // equivalent to ((j * k) / l) % m
[编辑] 内置乘法运算符
对于内置的乘法和除法运算符,两个操作数都必须具有算术或无作用域枚举类型。 对于内置的取余运算符,两个操作数都必须具有整数或无作用域枚举类型。 常用算术转换 在两个操作数上执行。
在本节的其余描述中,“操作数”,lhs 和 rhs 指的是转换后的操作数。
- NaN 乘以任何数字都得到 NaN。
- 无穷大乘以零得到 NaN,并引发 FE_INVALID。
- 如果一个操作数是 NaN,则结果为 NaN。
- 将非零数除以 ±0.0 会给出正确符号的无穷大,并引发 FE_DIVBYZERO。
- 0.0 除以 0.0 得到 NaN,并引发 FE_INVALID。
注意:在 CWG issue 614 解决之前 (N2757),如果二元运算符 % 的一个或两个操作数为负数,则余数的符号是实现定义的,因为它取决于整数除法的舍入方向。 在这种情况下,函数 std::div 提供了明确定义的行为。
注意:对于浮点余数,请参见 std::remainder 和 std::fmod。
[编辑] 重载
在 针对用户定义的运算符的重载决议中,对于每对提升的算术类型 LA
和 RA
以及对于每对提升的整数类型 LI
和 RI
,以下函数签名参与重载决议
LRA operator*(LA, RA) |
||
LRA operator/(LA, RA) |
||
LRI operator%(LI, RI) |
||
其中 LRx
是 Lx
和 Rx
上 常用算术转换 的结果。
#include <iostream> int main() { char c = 2; unsigned int un = 2; int n = -10; std::cout << "2 * (-10), where 2 is a char = " << c * n << "\n" "2 * (-10), where 2 is unsigned = " << un * n << "\n" "-10 / 2.12 = " << n / 2.12 << "\n" "-10 / 21 = " << n / 21 << "\n" "-10 % 21 = " << n % 21 << '\n'; }
输出
2 * (-10), where 2 is a char = -20 2 * (-10), where 2 is unsigned = 4294967276 -10 / 2.12 = -4.71698 -10 / 21 = 0 -10 % 21 = -10
[编辑] 位逻辑运算符
位逻辑运算符表达式具有以下形式
~ rhs |
(1) | ||||||||
lhs & rhs |
(2) | ||||||||
lhs | rhs |
(3) | ||||||||
lhs ^ rhs |
(4) | ||||||||
位非运算符的优先级高于所有二元算术运算符。 它从右到左结合
~a - b; // equivalent to (~a) - b, NOT ~(a - b) ~c * d; // equivalent to (~c) * d, NOT ~(c * d) ~-e; // equivalent to ~(-e)
当 ~ 后跟 类型名称 或 decltype
说明符(自 C++11 起) 时,语法上存在歧义:它可以是 operator~ 或启动 析构函数 标识符)。 歧义通过将 ~ 视为 operator~ 来解决。 ~ 只能在语法上无效形成 operator~ 的地方启动析构函数标识符。
所有其他位逻辑运算符的优先级都低于所有其他二元算术运算符。 位与的优先级高于位异或,位异或的优先级高于位或。 它们从左到右结合
a & b * c; // equivalent to a & (b * c), NOT (a & b) * c d / e ^ f; // equivalent to (d / e) ^ f, NOT d / (e ^ f) g << h | i; // equivalent to (g << h) | i, NOT g << (h | i) j & k & l; // equivalent to (j & k) & l m | n ^ o // equivalent to m | (n ^ o)
[编辑] 内置位逻辑运算符
对于内置的位非运算符,rhs 必须是整数或无作用域枚举类型的纯右值,并且对 rhs 执行整数提升。 对于其他内置位逻辑运算符,两个操作数都必须具有整数或无作用域枚举类型,并且 常用算术转换 在两个操作数上执行。
在本节的其余描述中,“操作数”、“左操作数”和“右操作数”指的是转换后或提升后的操作数。
- 换句话说,结果是操作数的反码(其中操作数和结果被视为无符号)。
[编辑] 重载
在 针对用户定义的运算符的重载决议中,对于每对提升的整数类型 L
和 R
,以下函数签名参与重载决议
R operator~(R) |
||
LR operator&(L, R) |
||
LR operator^(L, R) |
||
LR operator|(L, R) |
||
其中 LR
是 L
和 R
上 常用算术转换 的结果。
#include <bitset> #include <cstdint> #include <iomanip> #include <iostream> int main() { std::uint16_t mask = 0x00f0; std::uint32_t x0 = 0x12345678; std::uint32_t x1 = x0 | mask; std::uint32_t x2 = x0 & ~mask; std::uint32_t x3 = x0 & mask; std::uint32_t x4 = x0 ^ mask; std::uint32_t x5 = ~x0; using bin16 = std::bitset<16>; using bin32 = std::bitset<32>; std::cout << std::hex << std::showbase << "Mask: " << mask << std::setw(49) << bin16(mask) << "\n" "Value: " << x0 << std::setw(42) << bin32(x0) << "\n" "Setting bits: " << x1 << std::setw(35) << bin32(x1) << "\n" "Clearing bits: " << x2 << std::setw(34) << bin32(x2) << "\n" "Selecting bits: " << x3 << std::setw(39) << bin32(x3) << "\n" "XOR-ing bits: " << x4 << std::setw(35) << bin32(x4) << "\n" "Inverting bits: " << x5 << std::setw(33) << bin32(x5) << '\n'; }
输出
Mask: 0xf0 0000000011110000 Value: 0x12345678 00010010001101000101011001111000 Setting bits: 0x123456f8 00010010001101000101011011111000 Clearing bits: 0x12345608 00010010001101000101011000001000 Selecting bits: 0x70 00000000000000000000000001110000 XOR-ing bits: 0x12345688 00010010001101000101011010001000 Inverting bits: 0xedcba987 11101101110010111010100110000111
[编辑] 位移位运算符
位移位运算符表达式具有以下形式
lhs << rhs |
(1) | ||||||||
lhs >> rhs |
(2) | ||||||||
位移位运算符的优先级高于位逻辑运算符,但低于加法和乘法运算符。 这些运算符从左到右结合
a >> b * c; // equivalent to a >> (b * c), NOT (a >> b) * c d << e & f; // equivalent to (d << e) & f, NOT d << (e & f) g << h >> i; // equivalent to (g << h) >> i, NOT g << (h >> i)
[编辑] 内置位移位运算符
对于内置位移位运算符,两个操作数都必须是整数或无作用域枚举类型的纯右值。 整数提升在两个操作数上执行。
在本节的其余描述中,“操作数”,a,b,lhs 和 rhs 指的是转换或提升后的操作数。
如果 rhs 的值为负数或不小于 lhs 中的位数,则行为是未定义的。
对于无符号 a,a << b 的值是 a * 2b 对于有符号且非负的 a,如果 a * 2b 对于负数 a,a << b 的行为是未定义的。 对于无符号 a 以及有符号且非负的 a,a >> b 的值是 a/2b 对于负数 a,a >> b 的值是实现定义的(在大多数实现中,这执行算术右移,因此结果保持为负数)。 |
(直到 C++20) |
a << b 的值是与 a * 2b a >> b 的值是 a/2b |
(自 C++20 起) |
结果的类型是 lhs 的类型。
[编辑] 重载
在 针对用户定义的运算符的重载决议中,对于每对提升的整数类型 L
和 R
,以下函数签名参与重载决议
L operator<<(L, R) |
||
L operator>>(L, R) |
||
#include <iostream> enum { ONE = 1, TWO = 2 }; int main() { std::cout << std::hex << std::showbase; char c = 0x10; unsigned long long ull = 0x123; std::cout << "0x123 << 1 = " << (ull << 1) << "\n" "0x123 << 63 = " << (ull << 63) << "\n" // overflow in unsigned "0x10 << 10 = " << (c << 10) << '\n'; // char is promoted to int long long ll = -1000; std::cout << std::dec << "-1000 >> 1 = " << (ll >> ONE) << '\n'; }
输出
0x123 << 1 = 0x246 0x123 << 63 = 0x8000000000000000 0x10 << 10 = 0x4000 -1000 >> 1 = -500
[编辑] 标准库
算术运算符为许多标准库类型重载。
[编辑] 一元算术运算符
实现一元 + 和一元 - ( std::chrono::duration<Rep,Period> 的公共成员函数) | |
将一元运算符应用于复数 (函数模板) | |
将一元算术运算符应用于 valarray 的每个元素 ( std::valarray<T> 的公共成员函数) |
[编辑] 加法运算符
(C++11) |
执行涉及时间点的加法和减法运算 (函数模板) |
实现以 duration 作为参数的算术运算 (函数模板) | |
(C++20) |
添加或减去 year_month_day 和一些年或月(函数) |
连接两个字符串,一个字符串和一个 char,或一个字符串和一个 string_view (函数模板) | |
递增或递减迭代器 ( std::reverse_iterator<Iter> 的公共成员函数)
| |
递增或递减迭代器 ( std::move_iterator<Iter> 的公共成员函数)
| |
对两个复数值或一个复数和一个标量执行复数算术运算 (函数模板) | |
将二元运算符应用于两个 valarray 的每个元素,或一个 valarray 和一个值 (函数模板) |
[编辑] 乘法运算符
实现以 duration 作为参数的算术运算 (函数模板) | |
对两个复数值或一个复数和一个标量执行复数算术运算 (函数模板) | |
将二元运算符应用于两个 valarray 的每个元素,或一个 valarray 和一个值 (函数模板) |
[编辑] 位逻辑运算符
执行二元 AND、OR、XOR 和 NOT ( std::bitset<N> 的公共成员函数) | |
对 bitset 执行二元逻辑运算 (函数模板) | |
将一元算术运算符应用于 valarray 的每个元素 ( std::valarray<T> 的公共成员函数)
| |
将二元运算符应用于两个 valarray 的每个元素,或一个 valarray 和一个值 (函数模板) |
[编辑] 位移位运算符
将二元运算符应用于两个 valarray 的每个元素,或一个 valarray 和一个值 (函数模板) | |
执行二元左移和右移 ( std::bitset<N> 的公共成员函数)
|
[编辑] 流插入/提取运算符
在整个标准库中,位移位运算符通常与 I/O 流 (std::ios_base& 或其派生类之一) 重载,作为左操作数和返回类型。 这种运算符被称为流插入和流提取运算符
提取格式化数据 ( std::basic_istream<CharT,Traits> 的公共成员函数) | |
提取字符和字符数组 (函数模板) | |
插入格式化数据 ( std::basic_ostream<CharT,Traits> 的公共成员函数) | |
插入字符数据或插入到右值流中 (函数模板) | |
序列化和反序列化复数 (函数模板) | |
执行 bitset 的流输入和输出 (函数模板) | |
对字符串执行流输入和输出 (函数模板) | |
(C++11) |
对伪随机数引擎执行流输入和输出 (函数模板) |
(C++11) |
对伪随机数分布执行流输入和输出 (函数模板) |
[编辑] 缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。
DR | 应用于 | 已发布行为 | 正确行为 |
---|---|---|---|
CWG 614 | C++98 | 整数除法的代数商是 在实现定义的方向上舍入 |
整数的代数商 除法向零截断 (小数部分被丢弃) |
CWG 1450 | C++98 | a / b 的结果是未指定的,如果 它在结果类型中不可表示 |
a / b 和 a % b 在这种情况下的行为都是未定义的 |
CWG 1457 | C++98 | 将正有符号值的最左边 1 位移入符号位的行为是未定义的使其明确定义 |
明确定义 |
CWG 1504 | C++98 | 数组元素的基础类子对象的指针 可以用于指针算术 |
在这种情况下,行为是 未定义的 |
CWG 1515 | C++98 | 只有声明为 unsigned 的无符号整数 才应遵守模 2n 的算术定律 |
适用于所有无符号整数 |
CWG 1642 | C++98 | 算术运算符允许其操作数为左值 | 某些操作数必须是右值 |
CWG 1865 | C++98 | CWG 问题 1504 的解决方案使涉及数组元素指针的指针算术的行为 涉及数组元素指针的指针算术的行为 如果指向类型和数组元素 类型在非顶层具有不同的 cv 限定符,则为未定义的 |
明确定义 |
CWG 1971 | C++98 | 对于 ~ 的歧义规则是否适用于诸如 ~X(0) 之类的情况,尚不清楚 对于 ~ 的歧义规则是否适用于诸如 ~X(0) 之类的情况,尚不清楚 |
该规则适用于此类情况 |
CWG 2419 | C++98 | 非数组对象的指针仅被视为 大小为 1 的数组的第一个元素的指针 在指针算术中,如果指针是通过 & 获得的 |
适用于所有指针 到非数组对象 |
CWG 2626 | C++98 | 内置 operator~ 的结果仅仅是“反码”,没有适当的定义 |
结果用 以 2 为基数的表示形式表示 |
CWG 2724 | C++20 | 算术右移的舍入方向不明确 | 已明确 |
CWG 2853 | C++98 | 对象末尾之后的指针可能 无法与整数相加或相减 |
它可以 |
[编辑] 参见
常用运算符 | ||||||
---|---|---|---|---|---|---|
赋值 | 递增 递减 |
算术 | 逻辑 | 比较 | 成员 访问 |
其他 |
a = b |
++a |
+a |
!a |
a == b |
a[...] |
函数调用 a(...) |
逗号 a, b | ||||||
条件 a ? b : c | ||||||
特殊运算符 | ||||||
static_cast 将一种类型转换为另一种相关类型 |
C 文档 关于 算术运算符
|