运算符对操作数做计算。多数运算得到一个新值,例如 a + b 得到和,a 与 b 本身不变。有的运算还会改写变量或完成输入输出:i++ 会把 i 加 1,std::cout << x 会向屏幕写出内容。这类除计算结果以外、对程序状态的改动,称为副作用。同一表达式里不要堆叠多处改写(例如 i = i++),以免求值顺序难以判断。表达式中的类型组合会触发类型转换规则,再与优先级、结合性一起决定求值顺序。C++ 在 C 语言算术、关系、逻辑运算符基础上,增加了作用域解析 ::、内存管理 new / delete、流插入 << 等。本节说明常用运算符的含义与注意点,并为条件分支中的布尔表达式打基础。
算术运算符
二元算术运算符包括加 +、减 -、乘 *、除 /、取模 %。一元 +、- 表示正负号。若两个操作数均为整型,/ 执行整数除法并截断小数部分;至少一方为浮点类型时,按浮点规则求商。% 仅用于整型,结果为除法的余数,除数为 0 属于未定义行为。
| 运算符 | 含义 | 例子 | 注意 |
|---|---|---|---|
+ | 加 | 10 + 3 结果为 13 | 与浮点混合时,整数会先转为浮点再算 |
- | 减 | 10 - 3 结果为 7 | 一元 -x 表示取负,例如 -10 |
* | 乘 | 10 * 3 结果为 30 | 整数相乘可能溢出,大数宜用更大类型 |
/ | 除 | 10 / 3 结果为 3;10.0 / 3 约为 3.33333 | 两个整数相除会丢掉小数;除数为 0 属于未定义行为 |
% | 取模(余数) | 10 % 3 结果为 1 | 只用于整型;初学用正数。除数为 0 属于未定义行为 |
#include <iostream>
int main() {
int a = 10, b = 3;
std::cout << a + b << " " << a / b << " " << a % b << std::endl;
double x = 10.0 / 3;
std::cout << x << std::endl;
return 0;
}自增与自减
++ 与 -- 将变量加 1 或减 1。前缀形式(如 ++i)先改值再参与所在表达式;后缀形式(如 i++)先以旧值参与表达式再改值。在单独语句中两者效果相同,在复杂表达式中混用多种副作用会降低可读性,宜拆成多行。
int i = 5;
int a = ++i; // i 变为 6,a 为 6
int j = 5;
int b = j++; // b 为 5,j 变为 6赋值与复合赋值
简单赋值 = 将右值赋给左值;复合赋值(如 +=、-=、*=)先运算再写回。赋值运算符从右向左结合,例如 a = b = c 等价于 a = (b = c)。
int n = 10;
n += 2;
n *= 3;关系与逻辑运算符
关系运算符 ==、!=、<、>、<=、>= 比较操作数,结果为 bool。逻辑与 &&、逻辑或 ||、逻辑非 ! 操作布尔或可向布尔转换的值。
&& 与 || 具有短路特性:若左侧已能决定整个表达式的真假,右侧不再求值。利用短路可避免对空指针解引用或对零做除法,但不应以副作用依赖“是否求值右侧”的写法。
int x = 5, y = 8;
bool ok = (x < y) && (y != 0);
bool either = (x == 0) || (y > 0);这里 x 为 5、y 为 8。因为 5 小于 8,且 8 不是 0,两侧都为真,所以 ok 为 true。&& 要求两侧同时成立,一侧为假则整体为假。因为 5 不等于 0,左侧为假,但 8 大于 0,右侧为真,所以 either 为 true。|| 只要一侧为真整体就为真;若左侧已经为真,右侧不再计算(短路)。
位运算(入门)
位运算符作用于整型的位模式,常用于标志位、掩码与底层协议;日常业务逻辑以算术与逻辑为主。
| 运算符 | 含义 |
|---|---|
& | 按位与 |
| | 按位或 |
^ | 按位异或 |
~ | 按位取反(一元) |
<< >> | 左移、右移 |
移位位数过大、或对负数右移的行为,需查阅所用标准版本与实现文档;初学阶段可先掌握算术与关系运算。
sizeof 与逗号运算符
sizeof(type) 或 sizeof expr 得到对象或类型所占字节数,在编译期求值,不计算表达式本身的副作用(对 sizeof 内表达式而言)。逗号运算符 , 从左到右依次求值各子表达式,整个表达式的值为最后一项的值,常见于 for 循环的更新子句。
std::cout << sizeof(int) << " " << sizeof(double) << std::endl;
for (int i = 0, j = 10; i < j; ++i, --j) {
// 使用逗号同时更新 i 与 j
}优先级与结合性(常用)
复杂表达式应使用括号明确意图;下表列出初学阶段最常遇到的优先级关系(自上而下大致从高到低,同一行内同级)。
| 级别(概略) | 运算符示例 |
|---|---|
| 一元 | ! ++ -- +(正号) -(负号) * & |
| 乘除模 | * / % |
| 加减 | + - |
| 关系 | < > <= >= |
| 相等 | == != |
| 逻辑与 | && |
| 逻辑或 | || |
| 三目 | ?: |
| 赋值 | = += 等(从右结合) |
| 逗号 | , |
流运算符 <<、>> 的优先级低于算术、高于逻辑与;链式输出 std::cout << a << b 依赖左结合。
#include <iostream>
int main() {
int a = 7, b = 4;
std::cout << (a / b) << " " << (a % b) << std::endl;
std::cout << ((a > b) && (b != 0)) << std::endl;
return 0;
}输出:
1 3
1因为 7 除以 4 的商是 1、余数是 3,所以第一行是 1 3。因为 7 大于 4 且 4 不是 0,两侧都为真,所以第二行打印 1(true 在默认格式下显示为 1)。
本节说明了 C++ 中常见运算符、短路逻辑与优先级要点。下一节介绍条件分支:if、else、switch 与三目运算符 ?:。