适用于中学生与信息学竞赛入门者
使用方向键
切换幻灯片
点击幻灯片
逐步展示内容
使用左上角按钮
打开目录
使用右上角按钮
切换主题
点击幻灯片任意位置或按下 → 键继续...
C++ 提供了丰富的运算符,用于执行各种操作。了解它们的分类有助于系统学习。
分类 | 常见运算符 | 简述 |
---|---|---|
➕算术运算符 | + , - , * , / , % , ++ , -- |
执行基本数学计算,如加减乘除、取余、自增自减。 |
🔍关系运算符 | == , != , > , < , >= , <= |
比较两个操作数的关系,结果为布尔值 (true 或 false )。 |
🔄逻辑运算符 | && (与), || (或), ! (非) |
连接或修改布尔表达式,用于构建复杂的条件判断。 |
📝赋值运算符 | = , += , -= , *= , /= , %= , &= , |= , ^= , <<= , >>= |
将值赋给变量,或执行运算后再赋值(复合赋值)。 |
🔢位运算符 | & , | , ^ , ~ , << , >> |
直接操作变量的二进制位,常用于底层编程或优化。 |
❓条件(三目)运算符 | ? : |
根据条件选择两个值中的一个,是 if-else 的简洁形式。 |
🔗其他运算符 | , (逗号), sizeof() , & (取地址), * (解引用), () (函数调用), [] (下标) 等 |
具有特定功能的运算符。 |
运算符是构成 C++ 表达式的基础,它们无处不在:
if
语句、while
/for
循环的条件判断。&
和 *
操作指针。学习提示:理解每个运算符的功能、需要的操作数类型以及返回结果的类型是关键。
#include <bits/stdc++.h>
int main() {
int a = 10, b = 4;
cout << "a + b = " << (a + b) << endl; // 输出: 14
cout << "a - b = " << (a - b) << endl; // 输出: 6
cout << "a * b = " << (a * b) << endl; // 输出: 40
cout << "a / b = " << (a / b) << endl; // 整数除法,输出: 2
cout << "a % b = " << (a % b) << endl; // 取模(余数),输出: 2
int c = 5;
cout << "c++ (后置): " << c++ << endl; // 先输出 5, 然后 c 变为 6
cout << "c 当前值: " << c << endl; // 输出: 6
cout << "++c (前置): " << ++c << endl; // c 先变为 7, 然后输出 7
double da = 10.0, db = 4.0;
cout << "da / db = " << (da / db) << endl; // 浮点数除法,输出: 2.5
return 0;
}
注意:整数除法 /
会舍弃小数部分。取模 %
运算通常用于整数。区分 前置++先将变量加1,再使用变量的值。 (++var
) 与 后置++先使用变量当前的值,再将变量加1。 (var++
)。
#include <bits/stdc++.h>
int main() {
int x = 5, y = 10, z = 5;
bool flag1 = true, flag2 = false;
// 关系运算
cout << boolalpha; // 让 bool 输出 true/false 而不是 1/0
cout << "x == z: " << (x == z) << endl; // 输出: true
cout << "x != y: " << (x != y) << endl; // 输出: true
cout << "x < y: " << (x < y) << endl; // 输出: true
cout << "y >= z: " << (y >= z) << endl; // 输出: true
// 逻辑运算
cout << "flag1 && flag2: " << (flag1 && flag2) << endl; // 逻辑与, 输出: false
cout << "flag1 || flag2: " << (flag1 || flag2) << endl; // 逻辑或, 输出: true
cout << "!flag1: " << (!flag1) << endl; // 逻辑非, 输出: false
// 组合使用
if ((x < y) && (x == z)) {
cout << "条件满足!" << endl; // 会输出
}
// 短路求值示例
int counter = 0;
// 因为 flag2 为 false,&& 右侧的 ++counter 不会执行
bool result_and = flag2 && (++counter > 0);
cout << "After &&, counter = " << counter << endl; // 输出: 0
// 因为 flag1 为 true,|| 右侧的 ++counter 不会执行
bool result_or = flag1 || (++counter > 0);
cout << "After ||, counter = " << counter << endl; // 输出: 0
return 0;
}
#include <bits/stdc++.h>
int main() {
int score = 100; // 基本赋值
score += 10; // score = score + 10; score 现在是 110
cout << "Score after += 10: " << score << endl;
score -= 20; // score = score - 20; score 现在是 90
cout << "Score after -= 20: " << score << endl;
score *= 2; // score = score * 2; score 现在是 180
cout << "Score after *= 2: " << score << endl;
score /= 3; // score = score / 3; score 现在是 60
cout << "Score after /= 3: " << score << endl;
score %= 7; // score = score % 7; score 现在是 4 (60除以7余4)
cout << "Score after %= 7: " << score << endl;
// 同样适用于位运算符
int flags = 5; // 二进制 0101
flags |= 2; // flags = flags | 2 (0010); flags 现在是 7 (0111)
cout << "Flags after |= 2: " << flags << endl;
return 0;
}
复合赋值运算符 (如 +=
, -=
) 是对应运算和赋值的简写形式,可以使代码更简洁。
#include <bits/stdc++.h>
int main() {
unsigned char a = 5; // 二进制: 0000 0101
unsigned char b = 12; // 二进制: 0000 1100
cout << "a = " << bitset<8>(a) << " (" << (int)a << ")" << endl;
cout << "b = " << bitset<8>(b) << " (" << (int)b << ")" << endl;
// 按位与 (&): 对应位都为1时,结果位才为1
unsigned char result_and = a & b; // 0000 0100
cout << "a & b = " << bitset<8>(result_and) << " (" << (int)result_and << ")" << endl; // 输出 4
// 按位或 (|): 对应位有一个为1时,结果位就为1
unsigned char result_or = a | b; // 0000 1101
cout << "a | b = " << bitset<8>(result_or) << " (" << (int)result_or << ")" << endl; // 输出 13
// 按位异或 (^): 对应位不同时,结果位为1;相同时为0
unsigned char result_xor = a ^ b; // 0000 1001
cout << "a ^ b = " << bitset<8>(result_xor) << " (" << (int)result_xor << ")" << endl; // 输出 9
// 按位非 (~): 对每一位取反 (0变1, 1变0)
unsigned char result_not_a = ~a; // 1111 1010
cout << "~a = " << bitset<8>(result_not_a) << " (" << (int)result_not_a << ")" << endl; // 输出 250
// 左移 (<<): 所有位向左移动指定位数,右侧补0
unsigned char result_left_shift = a << 2; // 0001 0100
cout << "a << 2 = " << bitset<8>(result_left_shift) << " (" << (int)result_left_shift << ")" << endl; // 输出 20 (相当于 5 * 2^2)
// 右移 (>>): 所有位向右移动指定位数
// 对于 unsigned 类型,左侧补0
// 对于 signed 类型,行为可能依赖实现 (通常补符号位 - 算术右移)
unsigned char result_right_shift = b >> 1; // 0000 0110
cout << "b >> 1 = " << bitset<8>(result_right_shift) << " (" << (int)result_right_shift << ")" << endl; // 输出 6 (相当于 12 / 2^1)
return 0;
}
应用场景:位运算常用于状态压缩用一个整数的不同位来表示多个布尔状态,节省空间。、快速乘除2的幂左移 `<< n` 相当于乘以 2n,右移 `>> n` 相当于除以 2n (对正整数)。、掩码操作、权限管理、加解密算法等。
? :
条件运算符提供了一种基于条件选择两个值之一的简洁方式。
语法: condition ? value_if_true : value_if_false
#include <iostream>
#include <string>
int main() {
int a = 10, b = 20;
int maxValue;
// 使用 if-else 找最大值
if (a > b) {
maxValue = a;
} else {
maxValue = b;
}
cout << "Max value (if-else): " << maxValue << endl; // 输出 20
// 使用条件运算符实现相同功能
maxValue = (a > b) ? a : b;
cout << "Max value (ternary): " << maxValue << endl; // 输出 20
// 也可以直接在输出中使用
cout << "The smaller value is: " << ((a < b) ? a : b) << endl; // 输出 10
// 根据分数判断等级
int score = 85;
string grade = (score >= 90) ? "优秀" : (score >= 60) ? "及格" : "不及格";
cout << "成绩 " << score << " 对应的等级是: " << grade << endl; // 输出 及格
return 0;
}
优点: 简洁。缺点: 嵌套过多会降低可读性。适合简单的条件赋值。
,
逗号运算符用于连接两个或多个表达式。它会从左到右依次计算每个表达式,并返回最右侧表达式的值。
#include <iostream>
int main() {
int a = 1, b = 2, c = 3, result;
// 表达式1: a++, 表达式2: b++, 表达式3: c++
result = (a++, b++, c++);
// a, b, c 都会自增
cout << "a = " << a << endl; // 输出: 2
cout << "b = " << b << endl; // 输出: 3
cout << "c = " << c << endl; // 输出: 4
// result 的值等于最后一个表达式 (c++) 的值 *在自增之前* 的值
cout << "result = " << result << endl; // 输出: 3
// 常见于 for 循环的初始化和迭代表达式
for (int i = 0, j = 10; i < j; i++, j--) {
cout << "i=" << i << ", j=" << j << " ";
}
cout << endl;
// 输出: i=0, j=10 i=1, j=9 i=2, j=8 i=3, j=7 i=4, j=6
return 0;
}
逗号运算符的优先级是最低的,需要注意括号的使用。
sizeof(type/variable)
: 返回类型或变量在内存中占用的字节数。
cout << "Size of int: " << sizeof(int) << " bytes" << endl;
&variable
(取地址): 返回变量的内存地址。
int num = 10; int* ptr = #
*pointer
(解引用): 访问指针指向地址的值。
cout << "Value pointed by ptr: " << *ptr << endl; // 输出 10
()
(函数调用): 调用函数。
int result = myFunction(arg1, arg2);
[]
(下标): 访问数组或容器元素。
int arr[] = {1, 2, 3}; int second = arr[1]; // second is 2
.
(成员访问): 访问对象或结构体的成员。
myObject.memberVariable = 5;
->
(指针成员访问): 通过指针访问对象或结构体的成员 (等价于 (*ptr).member
)。
myPointer->memberFunction();
这些运算符在 C++ 编程中非常基础和重要。
当一个表达式包含多个不同运算符时,优先级决定了哪个运算符先执行。优先级高的运算符先于优先级低的运算符进行计算。
例如:在 a + b * c
中,乘法 *
的优先级高于加法 +
,所以先计算 b * c
,再计算 a + (b * c)
。
当一个表达式包含多个相同优先级的运算符时,结合性决定了它们的执行顺序是从左到右还是从右到左。
a + b - c
等价于 (a + b) - c
。算术、关系、逻辑与/或、位运算等都是左结合。a = b = c
等价于 a = (b = c)
)、一元运算符 (! ++ -- ~ * &
等,如 *ptr++
会先执行 ++
再解引用)、条件运算符 (a ? b : c ? d : e
等价于 a ? b : (c ? d : e)
)。以下是常见运算符的优先级,从高到低排列(同一行优先级相近或相同):
::
() [] -> . ++ --
(后缀)++ -- ! ~ + - * & sizeof
(前缀/一元)* / %
+ -
<< >>
< <= > >=
== !=
&
(按位与)^
(按位异或)|
(按位或)&&
||
?:
= += -= *= /= %= &= ^= |= <<= >>=
,
最佳实践:不要过度依赖优先级规则!当表达式复杂或不确定时,使用括号 ()
来明确指定计算顺序,这样可以大大提高代码的可读性并减少错误。
// 不清晰
int result = a + b << 2 & c;
// 清晰
int result_clear = ((a + b) << 2) & c;
假设 int a = 5, b = 3, c = 2;
,请计算以下表达式的值:
1. a / c * b
2. a + b % c * a
3. (++a + b--) * c
注意:第3题会改变 a 和 b 的值。
解析:
a / c * b
=> 5 / 2 * 3
(整数除法) => 2 * 3
=> 6
(乘除优先级相同,左结合)a + b % c * a
=> 5 + 3 % 2 * 5
(取模和乘法优先级高于加法) => 5 + (3 % 2) * 5
=> 5 + 1 * 5
=> 5 + 5
=> 10
(% 和 * 优先级相同,左结合)(++a + b--) * c
:
++a
(前置自增): a 变为 6,表达式值为 6。b--
(后置自减): 表达式值为 3,之后 b 变为 2。(6 + 3) * c
=> 9 * 2
=> 18
假设 int x = 10;
(二进制 1010
), int y = 6;
(二进制 0110
), bool p = true, q = false;
判断以下表达式的结果 (true/false 或 整数值):
1. (x > 1) == (y & 5) // 5 的二进制是 0101
2. p || !q && q
3. x ^ y | 3 // 3 的二进制是 0011
解析:
(x >> 1) == (y & 5)
x >> 1
: 1010 >> 1
=> 0101
(十进制 5)y & 5
: 0110 & 0101
=> 0100
(十进制 4)5 == 4
=> false
p || !q && q
(!
优先级最高, 然后 &&
, 最后 ||
)
!q
: !false
=> true
true && q
: true && false
=> false
p || false
: true || false
=> true
x ^ y | 3
(^
和 |
中, ^
优先级略高)
x ^ y
: 1010 ^ 0110
=> 1100
(十进制 12)1100 | 0011
=> 1111
(十进制 15
)分析以下代码片段,执行后变量 a
, b
, result
的最终值是多少?
int a = 1, b = 2;
bool result = (--a == 0) && (b++ > 2);
解析:
这是一个利用逻辑与 &&
短路特性的例子。
--a
(前置自减): a
从 1 变为 0,表达式 --a
的值为 0。(--a == 0)
: 即 0 == 0
,结果为 true
。&&
左侧为 true
,需要继续计算右侧 (b++ > 2)
。b++
(后置自增): 表达式 b++
的值为 b
当前的值 2。之后 b
变为 3。(b++ > 2)
: 即 2 > 2
,结果为 false
。true && false
,结果为 false
。false
赋值给 result
。最终结果:
a
= 0b
= 3result
= false&&
, ||
) 具有短路求值特性。()
来明确意图,提高代码可读性。+=
, -=
等) 和条件运算符 (?:
) 可以让代码更简洁,但前提是不牺牲可读性。运算符只是 C++ 语言的一部分。接下来你可以继续探索:
祝你在 C++ 的学习道路上不断进步!