| 类别 | 运算符 | ||
|---|---|---|---|
| 算术运算符 | +, -, *, /, %, ++, -- | ||
| 关系运算符 | >, <, ==, >=, <=, != | ||
| 逻辑运算符 | !, &&, ` | ` | |
| 位运算符 | <<, >>, ~, ` | , &, ^(不同为1)` | |
| 赋值运算符 | =, +=, -=, *=, =, %=, <<=, >>=, &=, ` | =, ^=` | |
| 条件运算符 | ?: | ||
| 逗号运算符 | , | ||
| 指针运算符 | &, * | ||
| 求字节数运算符 | sizeof | ||
| 强制类型转换运算符 | (类型) | ||
| 成员运算符 | ., -> | ||
| 下标运算符 | [] | ||
| 其他 | 函数调用运算符 () |
| 类别 | 运算符 | 优先级 | 结合性 | ||
|---|---|---|---|---|---|
| 函数和表达式结构 | (), [], ->, . | 最高 | 从左至右 | ||
| 一元运算符 | !, ~, ++, --, -, (类型), *, &, sizeof | 高 | 从右至左 | ||
| 乘除法 | *, /, % | 中等 | 从左至右 | ||
| 加减法 | +, - | 中等 | 从左至右 | ||
| 位移 | <<, >> | 中等 | 从左至右 | ||
| 关系 | <, <=, >, >= | 中等 | 从左至右 | ||
| 相等性 | ==, != | 中等 | 从左至右 | ||
| 位运算 | **&, ^(XOR), ` | `(并存时,优先级左至右)** | 中等 | 从左至右 | |
| 逻辑运算 | **&&, ` | `(并存时,优先级左至右)** | 中等 | 从左至右 | |
| 条件运算 | ? : | 低 | 从右至左 | ||
| 赋值 | **=, +=, -=, *=, /=, %=, >>=, <<=, &=, ^=, ` | =`** | 最低 | 从右至左 | |
| 逗号 | , | 最低 | 从左至右 |

位运算
跳转到“位运算”*((volatile size_t*)gpioe_cfg1) &= ~(7 << 16); // 清除原配置*((volatile size_t*)gpioe_cfg1) |= (1 << 16); // 设置为输出*((volatile size_t*)gpioe_pul0) &= ~(3 << 16); // 清除上/下拉配置*((volatile size_t*)gpioe_pul0) |= (1 << 12); // 设置为上拉
/*~(7 << 16) 是一个位掩码,`7 << 16` 表示`7` 左移 `16` 位的结果。效果是将 GPIOE_CFG1 寄存器中第 `16` 位开始的 `3` 个位清零,而其他位不受影响。00000000000000000000000000000111 原数字700000000000001110000000000000000 左移16位11111111111110001111111111111111 取反
|= (1 << 16) 的效果是将原始整数中第 16 位设置为 1,而其他位保持不变。00000000000000000000000000000001 原数字100000000000000010000000000000000 左移16位*/类型自动转换
跳转到“类型自动转换”// 32 bitunsigned a = 4;int b = -16;printf(a + b);
/*负数在内存采用补码保存:原码为10000000000000000000000000010000反码为11111111111111111111111111101111补码为11111111111111111111111111110000a正数在内存采用原码保存:原码为00000000000000000000000000000100反码为00000000000000000000000000000100反码为00000000000000000000000000000100
在内存中 a+b :00000000000000000000000000000100 + 11111111111111111111111111110000= 11111111111111111111111111110100= 4,294,967,284类型为 unsigned a*/原码表示方法:最高位为符号位,1表示负数,0表示正数。其余比特位表示数值。 反码表示方法:正数的反码是其本身,负数的反码为在原码的基础上,符号位不变,其余位取反。 补码表示方法:正数的补码就是其本身,负数的补码为在原码的基础上,符号位不变,其余位取反,再+1(即在反码的基础上+1)。
重载运算符
跳转到“重载运算符”(1)运算符重载的用途
- 使自定义类型更直观:通过运算符重载,你可以使自定义类型的对象像内置类型一样进行操作,例如通过
+运算符来合并两个自定义类型的对象。 - 提高代码可读性:对于某些操作,使用运算符可能比调用成员函数更直观,从而使代码更容易理解。
- 实现特定的行为:在某些情况下,你可能希望自定义类型的某些操作与内置类型不同,运算符重载提供了这种灵活性。
(2)基本格式
运算符重载通常作为类的成员函数或非成员函数实现。其基本格式如下:
作为成员函数
class ClassName {public: 返回类型 operator运算符(参数列表) { // 实现 }};作为非成员函数
返回类型 operator运算符(参数列表) { // 实现}步骤
-
确定运算符:首先确定你想要重载的运算符。不是所有运算符都可以重载,有些(如
?:)是不允许重载的。 -
选择成员或非成员:确定运算符重载是作为类的成员函数实现还是作为非成员函数实现。一些运算符(如赋值
=、下标[]、调用()和成员访问箭头->)必须作为成员函数重载。 -
编写函数体:实现运算符的具体功能。确保它符合运算符的预期行为和语义。
-
返回类型:根据需要选择适当的返回类型。通常,赋值和流操作符会返回引用,而算术运算符可能返回新对象。
(3)示例
重载加法运算符,作为成员函数:
class Point {public: int x, y;
Point(int x, int y) : x(x), y(y) {}
Point operator+(const Point& other) const { return Point(x + other.x, y + other.y); }};重载输出流运算符,作为非成员函数:
std::ostream& operator<<(std::ostream& os, const Point& point) { os << "(" << point.x << ", " << point.y << ")"; return os;}注意事项
- 确保重载的运算符行为符合直觉和标准运算符的预期行为。
- 考虑运算符重载对类的封装性和接口的影响。
- 考虑运算符的对称性(如
+和*应该是对称的)。 - 注意处理自赋值情况,尤其是在重载赋值运算符
=时。
标准类型转换运算符
跳转到“标准类型转换运算符”C++中的四种标准类型转换运算符
| 类型转换运算符 | 说明 | 用途 | 代码示例 |
|---|---|---|---|
static_cast | 用于非多态的转换,编译时检查。 | 基本数据类型转换,向上转型(如派生类指针到基类指针)。 | int i = 10; double d = static_cast<double>(i); |
| 可以用于类层次结构中的转换,但仅限于向上转型。 | 不能用于向下转型或改变对象的 const 属性。 | ||
| 不涉及多态性。 | |||
dynamic_cast | 用于类层次结构中的向下转型和多态性相关的转换,运行时检查。 | 安全向下转型,需要类层次结构中有虚函数。 | Base* b = new Derived(); Derived* d = dynamic_cast<Derived*>(b); |
| 涉及多态性。 | 可以用于安全的向下转型。 | ||
| 转换失败时返回空指针(指针转换)或抛出异常(引用转换)。 | |||
const_cast | 用于移除或添加 const 属性,不改变值的类型。 | 改变对象的 const 属性。 | const int* ci = new int(10); int* modifiable = const_cast<int*>(ci); |
| 不涉及类型转换。 | 可以用于修改 const 对象。 | ||
reinterpret_cast | 用于低级别的重新解释类型转换,如指针到整数的转换。 | 强制类型转换,不安全。 | int* p = new int(20); char* ch = reinterpret_cast<char*>(p); |
| 转换不安全,可能会丢失信息。 | 用于指针和引用类型之间的转换,不推荐在普通类型转换中使用。 |
++i & i++
跳转到“++i & i++”原则:
1)i++和++i都可视为一个带有返回的函数;
2)i++返回常量,++i返回变量i的引用或指针
i=1;
printf("%d", i++ + i++);>> 1 + 2 = 3
printf("%d", i++ + ++i);>> 1 + 3 = 4
printf("%d", ++i + ++i);>> 3 + 3 = 6