C++ 运算符
概述
运算符是执行特定数学或逻辑操作的符号。C++提供了丰富的内置运算符,包括算术、关系、逻辑、位运算、赋值等多种类型。理解和正确使用运算符是C++编程的基础。
🔢 算术运算符
基本算术运算
cpp
#include <iostream>
int main() {
int a = 15, b = 4;
double x = 15.0, y = 4.0;
std::cout << "=== 整数算术运算 ===" << std::endl;
std::cout << "a + b = " << (a + b) << std::endl; // 加法: 19
std::cout << "a - b = " << (a - b) << std::endl; // 减法: 11
std::cout << "a * b = " << (a * b) << std::endl; // 乘法: 60
std::cout << "a / b = " << (a / b) << std::endl; // 整数除法: 3
std::cout << "a % b = " << (a % b) << std::endl; // 取余: 3
std::cout << "\n=== 浮点数算术运算 ===" << std::endl;
std::cout << "x / y = " << (x / y) << std::endl; // 浮点除法: 3.75
return 0;
}自增自减运算符
cpp
#include <iostream>
int main() {
int i = 5, j = 5;
std::cout << "=== 自增自减运算符 ===" << std::endl;
// 前置自增/自减:先运算,后使用
std::cout << "++i = " << ++i << std::endl; // 输出6,i变为6
std::cout << "--j = " << --j << std::endl; // 输出4,j变为4
// 后置自增/自减:先使用,后运算
i = 5; j = 5; // 重置
std::cout << "i++ = " << i++ << std::endl; // 输出5,i变为6
std::cout << "j-- = " << j-- << std::endl; // 输出5,j变为4
// 复合赋值运算符
int x = 10;
x += 5; // x = x + 5 = 15
x *= 2; // x = x * 2 = 30
x /= 3; // x = x / 3 = 10
std::cout << "复合赋值后 x = " << x << std::endl;
return 0;
}🔍 关系运算符
比较运算符
cpp
#include <iostream>
int main() {
int a = 10, b = 20;
std::cout << "=== 关系运算符 ===" << std::endl;
std::cout << std::boolalpha; // 以true/false形式输出
std::cout << "a == b: " << (a == b) << std::endl; // false
std::cout << "a != b: " << (a != b) << std::endl; // true
std::cout << "a < b: " << (a < b) << std::endl; // true
std::cout << "a > b: " << (a > b) << std::endl; // false
std::cout << "a <= b: " << (a <= b) << std::endl; // true
std::cout << "a >= b: " << (a >= b) << std::endl; // false
// 字符串比较
std::string str1 = "apple", str2 = "banana";
std::cout << "\"apple\" < \"banana\": " << (str1 < str2) << std::endl; // true
return 0;
}🧠 逻辑运算符
逻辑与或非
cpp
#include <iostream>
int main() {
bool p = true, q = false;
std::cout << "=== 逻辑运算符 ===" << std::endl;
std::cout << std::boolalpha;
// 逻辑与 (&&):所有操作数都为true时才为true
std::cout << "p && q: " << (p && q) << std::endl; // false
std::cout << "p && true: " << (p && true) << std::endl; // true
// 逻辑或 (||):任一操作数为true时就为true
std::cout << "p || q: " << (p || q) << std::endl; // true
std::cout << "q || false: " << (q || false) << std::endl; // false
// 逻辑非 (!):取反
std::cout << "!p: " << (!p) << std::endl; // false
std::cout << "!q: " << (!q) << std::endl; // true
// 短路求值:避免不必要的计算或错误
int a = 0;
if (a != 0 && 10 / a > 1) { // a != 0为false,不会执行10/a(避免除零)
std::cout << "不会执行" << std::endl;
}
return 0;
}🔧 位运算符
基本位运算
cpp
#include <iostream>
#include <bitset>
int main() {
unsigned char a = 60; // 0011 1100
unsigned char b = 13; // 0000 1101
std::cout << "=== 位运算符 ===" << std::endl;
std::cout << "a = " << std::bitset<8>(a) << " (" << (int)a << ")" << std::endl;
std::cout << "b = " << std::bitset<8>(b) << " (" << (int)b << ")" << std::endl;
// 按位与 (&):两位都为1时结果为1
std::cout << "a & b = " << std::bitset<8>(a & b) << " (" << (int)(a & b) << ")" << std::endl;
// 按位或 (|):任一位为1时结果为1
std::cout << "a | b = " << std::bitset<8>(a | b) << " (" << (int)(a | b) << ")" << std::endl;
// 按位异或 (^):两位不同时结果为1
std::cout << "a ^ b = " << std::bitset<8>(a ^ b) << " (" << (int)(a ^ b) << ")" << std::endl;
// 按位取反 (~):0变1,1变0
std::cout << "~a = " << std::bitset<8>(~a) << " (" << (int)(unsigned char)(~a) << ")" << std::endl;
// 左移 (<<):向左移动指定位数
std::cout << "a << 2 = " << std::bitset<8>(a << 2) << " (" << (int)(a << 2) << ")" << std::endl;
// 右移 (>>):向右移动指定位数
std::cout << "a >> 2 = " << std::bitset<8>(a >> 2) << " (" << (int)(a >> 2) << ")" << std::endl;
return 0;
}位运算应用:权限管理
cpp
#include <iostream>
class PermissionManager {
public:
enum Permission {
READ = 1 << 0, // 0001 = 1
WRITE = 1 << 1, // 0010 = 2
EXECUTE = 1 << 2, // 0100 = 4
DELETE = 1 << 3 // 1000 = 8
};
private:
unsigned int permissions_ = 0;
public:
void addPermission(Permission perm) {
permissions_ |= perm; // 使用或运算添加权限
}
void removePermission(Permission perm) {
permissions_ &= ~perm; // 使用与非运算移除权限
}
bool hasPermission(Permission perm) const {
return (permissions_ & perm) != 0; // 检查权限
}
void printPermissions() const {
std::cout << "权限: ";
if (hasPermission(READ)) std::cout << "R";
if (hasPermission(WRITE)) std::cout << "W";
if (hasPermission(EXECUTE)) std::cout << "X";
if (hasPermission(DELETE)) std::cout << "D";
std::cout << std::endl;
}
};
int main() {
std::cout << "=== 位运算应用:权限管理 ===" << std::endl;
PermissionManager pm;
pm.printPermissions(); // 无权限
pm.addPermission(PermissionManager::READ);
pm.addPermission(PermissionManager::WRITE);
pm.printPermissions(); // RW
pm.addPermission(PermissionManager::EXECUTE);
pm.printPermissions(); // RWX
pm.removePermission(PermissionManager::WRITE);
pm.printPermissions(); // RX
return 0;
}📋 其他重要运算符
条件运算符和指针运算符
cpp
#include <iostream>
int main() {
std::cout << "=== 条件运算符 (三元运算符) ===" << std::endl;
int a = 10, b = 20;
// 语法: condition ? value_if_true : value_if_false
int max_value = (a > b) ? a : b;
std::cout << "max(" << a << ", " << b << ") = " << max_value << std::endl;
std::string grade = (85 >= 60) ? "及格" : "不及格";
std::cout << "85分: " << grade << std::endl;
std::cout << "\n=== 指针运算符 ===" << std::endl;
int value = 42;
int* ptr = &value; // 取地址运算符 &
std::cout << "value = " << value << std::endl;
std::cout << "ptr = " << ptr << std::endl;
std::cout << "*ptr = " << *ptr << std::endl; // 解引用运算符 *
*ptr = 100; // 通过指针修改值
std::cout << "修改后 value = " << value << std::endl;
std::cout << "\n=== sizeof 运算符 ===" << std::endl;
std::cout << "sizeof(int): " << sizeof(int) << " 字节" << std::endl;
std::cout << "sizeof(double): " << sizeof(double) << " 字节" << std::endl;
int array[10];
std::cout << "数组元素个数: " << sizeof(array) / sizeof(array[0]) << std::endl;
return 0;
}🎯 运算符优先级
优先级和结合性
cpp
#include <iostream>
int main() {
std::cout << "=== 运算符优先级演示 ===" << std::endl;
// 算术运算符优先级: * / % > + -
int result1 = 2 + 3 * 4; // 等同于 2 + (3 * 4) = 14
int result2 = (2 + 3) * 4; // 使用括号改变优先级 = 20
std::cout << "2 + 3 * 4 = " << result1 << std::endl;
std::cout << "(2 + 3) * 4 = " << result2 << std::endl;
// 关系运算符优先级低于算术运算符
bool result3 = 5 + 3 > 6 * 1; // 等同于 (5 + 3) > (6 * 1)
std::cout << "5 + 3 > 6 * 1 = " << std::boolalpha << result3 << std::endl;
// 逻辑运算符优先级: ! > && > ||
bool a = true, b = false, c = true;
bool result4 = a || b && c; // 等同于 a || (b && c)
std::cout << "a || b && c = " << result4 << std::endl;
// 赋值运算符的右结合性
int x, y, z;
x = y = z = 10; // 等同于 x = (y = (z = 10))
std::cout << "连续赋值后: x=" << x << ", y=" << y << ", z=" << z << std::endl;
return 0;
}常用优先级表(从高到低)
cpp
/*
运算符优先级表(部分,从高到低):
1. () [] -> . // 后缀表达式
2. ! ~ ++ -- + - * & // 一元运算符
3. * / % // 乘除取余
4. + - // 加减
5. << >> // 位移
6. < <= > >= // 关系运算符
7. == != // 相等性运算符
8. & // 按位与
9. ^ // 按位异或
10. | // 按位或
11. && // 逻辑与
12. || // 逻辑或
13. ?: // 条件运算符
14. = += -= *= /= %= etc. // 赋值运算符
15. , // 逗号运算符
记忆技巧:
- 括号优先级最高
- 一元运算符优先于二元运算符
- 算术 > 关系 > 逻辑 > 赋值
- 当不确定时,使用括号明确优先级
*/🛡️ 运算符使用最佳实践
安全编程技巧
cpp
#include <iostream>
int main() {
std::cout << "=== 运算符最佳实践 ===" << std::endl;
// 1. 避免未定义行为
int i = 5;
// int bad = ++i + i++; // 未定义行为!不要这样写
int good = ++i + 10; // 安全的写法
std::cout << "安全计算结果: " << good << std::endl;
// 2. 使用括号明确优先级
bool condition = (a > 0) && (b < 10) || (c == 5); // 清晰易读
// 3. 避免浮点数直接比较
double x = 0.1 + 0.2;
double y = 0.3;
// if (x == y) // 可能失败!
const double EPSILON = 1e-9;
if (std::abs(x - y) < EPSILON) {
std::cout << "浮点数相等(使用误差范围)" << std::endl;
}
// 4. 整数除法注意
int a = 7, b = 3;
double precise_result = static_cast<double>(a) / b; // 强制转换
std::cout << "精确除法: " << precise_result << std::endl;
// 5. 位运算使用无符号类型
unsigned int flags = 0xFFFFFFFF;
flags = flags >> 1; // 无符号右移,左边补0
return 0;
}总结
C++运算符是编程的基础工具,掌握它们的使用至关重要:
主要运算符类型
- 算术运算符:+, -, *, /, %, ++, --
- 关系运算符:==, !=, <, >, <=, >=
- 逻辑运算符:&&, ||, !
- 位运算符:&, |, ^, ~, <<, >>
- 赋值运算符:=, +=, -=, *=, /=, %=
关键概念
- 优先级:决定运算顺序,使用括号明确意图
- 结合性:相同优先级运算符的计算方向
- 短路求值:逻辑运算符的优化特性
- 类型转换:不同类型间的运算规则
最佳实践
- 使用括号明确运算优先级
- 避免复杂的自增自减表达式
- 浮点数比较使用误差范围
- 位运算优先使用无符号类型
- 保持代码可读性和安全性
理解运算符的正确使用方法是编写高质量C++代码的基础。