C++操作符
1 操作符
~(补码运算符)
1 |
|
解释:
x = 0000 0001
~x = 1111 1110,-x
为负数,负数在计算机中用补码表示,所以符号位不变,取反加1
y = 1 0000 0010,1000 0010(BIN) = -2(DEX)
++操作符
1 |
|
大体上是类似的,但是i++
在计算时会用到中间变量,会占用更多的内存和时间,所以++i
更好
2 C++不能重载的操作符
1 |
|
3 运算符重载后,优先级和结合性怎么办?
用户重载新定义运算符,不改变元运算符的优先级和结合性。这就是说,对运算符重载不改变运算的优先级和结合性,并且运算符重载后,也不改变运算符的语法结构,即单目运算符的语法结构只能冲仔尾单目运算符,双目运算符只能重载为双目运算符。
4 编译程序如何选用那一个运算符函数?
运算符重载实际是一个函数,所以运算符的重载实际上是函数的重载。编译程序对运算符重载的选择,遵循着函数重载的算则原则。当遇到不很明显的运算时,编译程序将去寻找参数相匹配的运算符函数。
5 重载你算符有哪些限制?
不可臆造新的运算符。必须把重载运算符限制在C++语言中已有的运算符范围内的允许重载的运算符之中。
重载运算符坚持4个“不能改变”
- 不能改变运算符操作数的个数;
- 不能改变运算符原有的优先级;
- 不能改变运算符原有的结核性;
- 不能改变运算符原有的语法结构。
6 运算符重载时必须遵循哪些原则?
运算符重载可以是程序更加简洁,是表达式更加直观,增加可读性。但是运算符重载使用不宜过多,否则会带来一定麻烦。
使用重载运算符是应遵循如下原则:
- 重载运算符含义必须清楚
- 重载运算符不能有二义性
以下是C++编程语言中的所有运算符的优先级和结合性列表。
优先级 | 运算符 | 叙述 | 示例 | 重载性 | 结合性 | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
1 |
:: |
作用域解析(C++专有) | Class::age = 2; |
否 | 由左至右 | ||||||
2 |
++ |
后缀递增 | i++ | ||||||||
2 |
-- |
后缀递减 | i— | ||||||||
2 |
{} |
组合 | {i++;a*=i;} | ||||||||
2 |
() |
函数调用或变量初始化 | c_tor(int x, int y) : _x(x), _y(y * 10) {} | ||||||||
2 |
[] |
数组访问 | array[4] = 2; | ||||||||
2 |
. |
以对象方式访问成员 | obj.age = 34; | 否 | |||||||
2 |
-> |
以指针方式访问成员 | ptr->age = 34; | ||||||||
2 |
dynamic_cast |
运行时检查类型转换(C++专有) | Y& y = dynamic_cast |
否 | |||||||
2 |
static_cast |
未经检查的类型转换(C++专有) | Y& y = static_cast |
否 | |||||||
2 |
reinterpret_cast |
重定义类型转换(C++专有) | int const p = reinterpret_cast<int const>(0x1234); | 否 | |||||||
2 |
const_cast |
更改非常量属性(C++专有) | int q = const_cast<int>(p); | 否 | |||||||
2 |
typeid |
获取类型信息(C++专有) | std::type_info const& t = typeid(x); | 否 | |||||||
3 |
++ |
前缀递增 | ++i | 由右至左 | |||||||
3 |
-- |
前缀递减 | —i | ||||||||
3 |
+ |
一元正号 | int i = +1; | ||||||||
3 |
- |
一元负号 | int i = -1; | ||||||||
3 |
! not |
逻辑非 ! 的备用拼写 |
if (!done) … | ||||||||
3 |
~ compl |
按位取反 ~ 的备用拼写 |
flag1 = ~flag2; | ||||||||
3 |
(*type*) |
强制类型转换 | int i = (int)floatNum; | ||||||||
3 |
* |
取指针指向的值 | int data = *intPtr; | ||||||||
3 |
& |
取变量的地址 | int *intPtr = &data; | ||||||||
3 |
sizeof |
某某的大小 | size_t s = sizeof(int); | 否 | |||||||
3 |
new |
动态内存分配(C++专有) | long* pVar = new long; | ||||||||
3 |
new[] |
动态数组内存分配(C++专有) | long* array = new long[20]; | ||||||||
3 |
delete |
动态内存释放(C++专有) | delete pVar; | ||||||||
3 |
delete[] |
动态数组内存释放(C++专有) | delete [] array; | ||||||||
4 |
.* |
成员对象选择(C++专有) | obj.*var = 24; | 否 | 由左至右 | ||||||
->* |
成员指针选择(C++专有) | ptr->*var = 24; | |||||||||
5 |
* |
乘法 | int i = 2 * 4; | ||||||||
/ |
除法 | float f = 10.0 / 3.0; | |||||||||
% |
模数(取余) | int rem = 4 % 3; | |||||||||
6 |
+ |
加法 | int i = 2 + 3; | ||||||||
- |
减法 | int i = 5 - 1; | |||||||||
7 |
<< |
比特左移 | int flags = 33 << 1; | ||||||||
>> |
比特右移 | int flags = 33 >> 1; | |||||||||
8 |
< |
小于关系 | if (i < 42) … | ||||||||
<= |
小于等于关系 | if (i <= 42) … | |||||||||
> |
大于关系 | if (i > 42) … | |||||||||
>= |
大于等于关系 | if (i >= 42) … | |||||||||
9 |
== eq |
等于关系 == 的备用拼写 |
if (i == 42) … | ||||||||
!= not_eq |
不等于关系 != 的备用拼写 |
if (i != 42) … | |||||||||
10 |
& bitand |
比特 AND & 的备用拼写 |
flag1 = flag2 & 42; | ||||||||
11 |
^ xor |
比特 XOR(独占or) ^ 的备用拼写 |
flag1 = flag2 ^ 42; | ||||||||
12 |
` | `bitor |
比特 OR(包含or) ` | `的备用拼写 | flag1 = flag2 \ | 42; | |||||
13 |
&& and |
逻辑 AND && 的备用拼写 |
if (conditionA && conditionB) … | ||||||||
14 |
` | `or |
逻辑 OR ` | `的备用拼写 | if (conditionA \ | \ | conditionB) … | ||||
15 |
*c*?*t*:*f* |
三元条件运算 | int i = a > b ? a : b; | 否 | 由右至左 | ||||||
16 |
= |
直接赋值 | int a = b; | ||||||||
16 |
+= |
以和赋值 | a += 3; | ||||||||
16 |
-= |
以差赋值 | b -= 4; | ||||||||
16 |
*= |
以乘赋值 | a *= 5; | ||||||||
16 |
/= |
以除赋值 | a /= 2; | ||||||||
16 |
%= |
以取余数赋值 | a %= 3; | ||||||||
16 |
<<= |
以比特左移赋值 | flags <<= 2; | ||||||||
16 |
>>= |
以比特右移赋值 | flags >>= 2; | ||||||||
16 |
&= and_eq |
以比特AND赋值 &= 的备用拼写 |
flags &= new_flags; | ||||||||
16 |
^= xor_eq |
以比特XOR赋值 ^= 的备用拼写 |
flags ^= new_flags; | ||||||||
16 |
` | =`or_eq |
以比特OR赋值 ` | =`的备用拼写 | flags \ | = new_flags; | |||||
17 |
throw |
抛出异常 | throw EClass(“Message”); | 否 | |||||||
18 |
, |
逗号运算符 | for (i = 0, j = 0; i < 10; i++, j++) … | 由左至右 |