操作符
运算符优先级顺口溜:
淡云一笔,鞍落三服
- 淡:单目运算符
- 云:算法运算符
- 一:移位运算符
- 笔:比较运算法
- 鞍:按位运算符
- 落:逻辑运算符
- 三:三目运算符
- 服:赋值运算符
~(补码运算符)
int x = 1;
int y = ~x; //1.
cout << y;
//输出'254'
解释:
x = 0000 0001
~x = 1111 1110,-x
为负数,负数在计算机中用补码表示,所以符号位不变,取反加1
y = 1 0000 0010,1000 0010(BIN) = -2(DEX)
![操作符1](http://tvax3.sinaimg.cn/large/0072YHp3ly1gjp909adtvj30ep02b0sj.jpg)
++操作符
int i1 = 4;
int y1 = i1++; //如大家所知,点调用、再自增 y1 = 4 , i1 = 5;
int i2 = 4;
int y2 = ++i2; //先自增再调用 y2 = 5 , i2 = 5;
大体上是类似的,但是i++
在计算时会用到中间变量,会占用更多的内存和时间,所以++i
更好
C++不能重载的操作符
(1) "."(类成员访问运算符)
(2)" .*"(类成员指针访问运算符)
(3) "::"(域运算符)
(4)"sizeof"(长度运算符)
(5) " ?:"(条件运算符/三目运算符)
(6) dynamic_cast
(7) static_cast
(8) reinterpret_cast
(9) const_cast
(10) typeid(获取类型信息)
运算符重载后,优先级和结合性怎么办?
用户重载新定义运算符,不改变元运算符的优先级和结合性。这就是说,对运算符重载不改变运算的优先级和结合性,并且运算符重载后,也不改变运算符的语法结构,即单目运算符的语法结构只能冲仔尾单目运算符,双目运算符只能重载为双目运算符。
编译程序如何选用那一个运算符函数?
运算符重载实际是一个函数,所以运算符的重载实际上是函数的重载。编译程序对运算符重载的选择,遵循着函数重载的算则原则。当遇到不很明显的运算时,编译程序将去寻找参数相匹配的运算符函数。
重载你算符有哪些限制?
-
不可臆造新的运算符。必须把重载运算符限制在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<Y&>(x); | 否 | |
2 | static_cast | 未经检查的类型转换(C++专有) | Y& y = static_cast<Y&>(x); | 否 | |
2 | reinterpret_cast | 重定义类型转换(C++专有) | int const* p = reinterpret_cast<int const*>(0x1234); | 否 | |
2 | const_cast | 更改非常量属性(C++专有) | int* q = const_cast<int*>§; | 否 | |
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++) … | 由左至右 |