运算符与优先级
运算符
运算符用于标识符之间,它们共同构成一组表达式。为了方便新手入门,这里不会一股脑地列出全部运算符,而是先介绍一些常见、常用的运算符。为了方便理解,接下来的所有运算符的参数均默认依次为 ,以此类推。
C++
赋值运算符
赋值运算符用于将右侧表达式的值赋予左侧变量,支持链式操作和组合运算。
基础赋值 | = |
将右侧值赋予左侧变量 | int b = a; (b=5 ) |
需要特别注意的是,连续赋值需分步操作,例如 int a = b = 5;
是错误写法,应拆分为 int b = 5; int a = b;
。
五大基本数学运算符
五大基本数学运算的运算参数为整数或浮点数类型,实实在在的数字。
这几个运算符相比大家已经十分熟悉了,相信大部分的人看完下面举得例子就能看懂这些运算符的含义了。
运算符 | + | - | * | / | % |
举例 | 5+7 (结果为12) |
5-7 (结果为-2) |
5*7 (结果为35) |
35/7 (结果为5) |
35%3(结果为2) |
需要特别注意的是,C++ 中的除号 /
只有当两个参与除法运算的参数中存在至少一个变量类型为浮点数时,才会保留运算结果的小数位。也就是说,如果参与运算的两个参数均为整数,则此时 /
将相当于整除,计算结果的小数点后部分将会被自动抹去。例如:5/3
的结果将不是 ,而是刨除掉小数点后的
。 此外,还需要满足除数不为
,否则将会出现除零错误导致代码 RE(Runtime Error)。
逻辑运算符
逻辑运算符的运算参数为布尔类型,即逻辑的真(true
)和假(false
)。
-
逻辑并运算符
&&
的含义类似与汉语中的并且,当且仅当两个参与运算的两个逻辑均为真时,运算的结果才为真。例如:“牛客里的所有人都很帅”为真命题,当且仅当“我很帅” 并且 “牛客全体员工除了我以外的人都很帅”这两个命题均为真命题。 -
逻辑或运算符
\|\|
的含义类似与汉语中的或者,只要两个参与运算的两个逻辑有一个为真,运算的结果就为真。例如:“牛客里存在很帅的人”为真命题,当且仅当“我很帅” 或者 “牛客全体员工除了我以外也有长得帅的人”这两个命题中至少有一个真命题。 -
逻辑非运算符
!
的含义类似与汉语中的并非,并非真即为假,并非假即为真。例如:假如“我很帅”是真命题,那么“我并非很帅”就是一个假命题。
运算符 | && |
|| |
! |
举例 | true && false (结果为 false ) |
true || false (结果为 true ) |
! true (结果为 false ) |
比较运算符
比较运算符返回布尔值(true
/false
),用于判断两个值的关系。
等于 | == |
判断两值是否相等 | a == 5 → true |
不等于 | != |
判断两值是否不等 | a != 3 → true |
大于 | > |
判断左值是否大于右值 | a > 3 → true |
小于 | < |
判断左值是否小于右值 | a < 10 → true |
大于等于 | >= |
判断左值是否不小于右值 | a >= 5 → true |
小于等于 | <= |
判断左值是否不大于右值 | a <= 5 → true |
需要特别注意的是,=
和 ==
是不一样的两个运算符,千万不要搞混!此外,浮点数由于存在误差,由不同计算过程得到的道理上说应该是相同的两个浮点数,在误差范围的部分却可能存在不同。因此,建议通过判断两个浮点数的差是否在精度范围内相当于 来判断浮点数是否相等是更为可靠的。
自增/自减运算符
用于快速对变量在自身值的基础上改变值的操作,分前置和后置两种形式。
前置自增 | ++i |
先增1,再使用变量值 | cout << ++i; → 输出 6 |
后置自增 | i++ |
先使用变量值,再增1 | cout << i++; → 输出 5 |
前置自减 | --i |
先减1,再使用变量值 | cout << --i; → 输出 4 |
后置自减 | i-- |
先使用变量值,再减1 | cout << i--; → 输出 5 |
加法赋值 | += |
a += b 等价于 a = a + b |
a += 3 → a=8 |
减法赋值 | -= |
a -= b 等价于 a = a - b |
a -= 2 → a=3 |
乘法赋值 | *= |
a *= b 等价于 a = a * b |
a *= 4 → a=20 |
除法赋值 | /= |
a /= b 等价于 a = a / b (整除特性) |
a /= 2 → a=2 |
取模赋值 | %= |
a %= b 等价于 a = a % b |
a %= 3 → a=2 |
需要特别注意的是,int b = a+++++a
会导致未定义行为,虽然你可能想表达的其实是 int b = a++ + ++a;
,但是这个写法太唐了。
位运算符(初学者了解即可)
直接操作二进制位,仅适用于整数类型。(0d
开头后面放数字表示这个数字是在二进制意义下的数字)
按位与 | & |
对应位同为1时结果为1 | a & 0b1100 → 0b1000 |
按位或 | | |
对应位有1时结果为1 | a | 0b1100 → 0b1110 |
按位异或 | ^ |
对应位不同时结果为1 | a ^ 0b1100 → 0b0110 |
按位取反 | ~ |
每一位取反(0变1,1变0) | ~a → 0b0101 (4位) |
左移 | << |
左移n位,低位补0 | a << 2 → 0b101000 |
右移 | >> |
右移n位,高位补符号位(有符号数) | a >> 1 → 0b0101 |
常用数学函数
根号 | sqrt(x) |
sqrt(9) (结果为 |
|
绝对值 | fabs(x) |
fabs(-7.6) (结果为 |
|
向上取整 | ceil(x) |
ceil(-7.6) (结果为 |
|
向下取整 | floor(x) |
floor(-7.6) (结果为 |
|
四舍五入 | round(x) |
round(-7.6) (结果为 |
|
幂函数 | pow(a,b) |
pow(2,6) (结果为 |
Java
赋值运算符
赋值运算符用于将右侧表达式的值赋予左侧变量,支持链式操作和组合运算。
基础赋值 | = |
将右侧值赋予左侧变量 | int b = a; (b=5 ) |
与C++不同,Java支持连续赋值,例如 int a = b = 5;
是合法的写法,此时先将5赋值给b,再将b的值赋给a。
五大基本数学运算符
Java的基本数学运算符与C++基本相同,用于整数和浮点数类型的计算。
运算符 | + | - | * | / | % |
举例 | 5+7 (结果为12) |
5-7 (结果为-2) |
5*7 (结果为35) |
35/7 (结果为5) |
35%3(结果为2) |
与C++类似,Java中的除法运算符 /
在两个操作数都是整数时执行整除,结果也是整数。如果至少有一个操作数是浮点数,则执行浮点除法。例如:5/3
结果为 1
,而 5.0/3
或 5/3.0
结果为 1.6666...
。同样,除数不能为0,否则会抛出 ArithmeticException
异常。
逻辑运算符
Java的逻辑运算符与C++相同,用于布尔类型的运算。
- 逻辑与运算符
&&
表示"并且",当且仅当两个操作数都为真时,结果才为真。 - 逻辑或运算符
||
表示"或者",只要有一个操作数为真,结果就为真。 - 逻辑非运算符
!
表示"取反",将真变为假,假变为真。
运算符 | && |
|| |
! |
举例 | true && false (结果为 false ) |
true || false (结果为 true ) |
! true (结果为 false ) |
Java还提供了按位逻辑运算符 &
、|
和 ^
,它们不仅可以用于整数的位运算,还可以用于布尔值的逻辑运算,但不具有短路特性。
比较运算符
Java的比较运算符与C++相同,返回布尔值(true
/false
)。
等于 | == |
判断两值是否相等 | a == 5 → true |
不等于 | != |
判断两值是否不等 | a != 3 → true |
大于 | > |
判断左值是否大于右值 | a > 3 → true |
小于 | < |
判断左值是否小于右值 | a < 10 → true |
大于等于 | >= |
判断左值是否不小于右值 | a >= 5 → true |
小于等于 | <= |
判断左值是否不大于右值 | a <= 5 → true |
需要注意的是,对于引用类型(如String、数组、对象等),==
比较的是引用是否指向同一对象,而不是内容是否相同。要比较内容,应使用 equals()
方法。
自增/自减运算符
Java的自增自减运算符与C++相同,分为前置和后置两种形式。
前置自增 | ++i |
先增1,再使用变量值 | System.out.println(++i); → 输出 6 |
后置自增 | i++ |
先使用变量值,再增1 | System.out.println(i++); → 输出 5 |
前置自减 | --i |
先减1,再使用变量值 | System.out.println(--i); → 输出 4 |
后置自减 | i-- |
先使用变量值,再减1 | System.out.println(i--); → 输出 5 |
加法赋值 | += |
a += b 等价于 a = a + b |
a += 3 → a=8 |
减法赋值 | -= |
a -= b 等价于 a = a - b |
a -= 2 → a=3 |
乘法赋值 | *= |
a *= b 等价于 a = a * b |
a *= 4 → a=20 |
除法赋值 | /= |
a /= b 等价于 a = a / b (整除特性) |
a /= 2 → a=2 |
取模赋值 | %= |
a %= b 等价于 a = a % b |
a %= 3 → a=2 |
位运算符
Java的位运算符与C++类似,仅适用于整数类型。
按位与 | & |
对应位同为1时结果为1 | a & 0b1100 → 0b1000 |
按位或 | | |
对应位有1时结果为1 | a | 0b1100 → 0b1110 |
按位异或 | ^ |
对应位不同时结果为1 | a ^ 0b1100 → 0b0110 |
按位取反 | ~ |
每一位取反(0变1,1变0) | ~a → 0b11111111111111111111111111110101 (32位) |
左移 | << |
左移n位,低位补0 | a << 2 → 0b101000 |
右移 | >> |
右移n位,高位补符号位 | a >> 1 → 0b0101 |
无符号右移 | >>> |
右移n位,高位补0(无符号右移) | a >>> 1 → 0b0101 |
Java特有的无符号右移运算符 >>>
不管符号位,右移后高位总是补0。
常用数学函数
Java的数学函数主要在 Math
类中提供。
根号 | Math.sqrt(x) |
Math.sqrt(9) (结果为 |
|
绝对值 | Math.abs(x) |
Math.abs(-7.6) (结果为 |
|
向上取整 | Math.ceil(x) |
Math.ceil(-7.6) (结果为 |
|
向下取整 | Math.floor(x) |
Math.floor(-7.6) (结果为 |
|
四舍五入 | Math.round(x) |
Math.round(-7.6) (结果为 |
|
幂函数 | Math.pow(a,b) |
Math.pow(2,6) (结果为 |
Python
赋值运算符
Python的赋值运算符比C++和Java更加灵活,支持多重赋值和解包赋值。
基础赋值 | = |
将右侧值赋予左侧变量 | b = 5 (b=5 ) |
多重赋值 | = |
同时为多个变量赋值 | a, b = 1, 2 (a=1, b=2 ) |
解包赋值 | = |
将可迭代对象的元素赋给多个变量 | a, b = [1, 2] (a=1, b=2 ) |
Python支持链式赋值,如 a = b = 5
,这会将5同时赋值给a和b。
七大基本数学运算符
Python的数学运算符比C++和Java更丰富,增加了整除和幂运算。
运算符 | + | - | * | / | // | % | ** |
举例 | 5+7 (结果为12) |
5-7 (结果为-2) |
5*7 (结果为35) |
5/3 (结果为1.6666...) |
5//3 (结果为1) |
5%3 (结果为2) |
2**3 (结果为8) |
Python的除法运算符 /
总是返回浮点数结果,即使操作数都是整数。如果需要整除,应使用 //
运算符。
逻辑运算符
Python使用英文单词作为逻辑运算符,更加直观。
- 逻辑与运算符
and
表示"并且",当且仅当两个操作数都为真时,结果才为真。 - 逻辑或运算符
or
表示"或者",只要有一个操作数为真,结果就为真。 - 逻辑非运算符
not
表示"取反",将真变为假,假变为真。
运算符 | and |
or |
not |
举例 | True and False (结果为 False ) |
True or False (结果为 True ) |
not True (结果为 False ) |
Python的逻辑运算符具有短路特性,并且返回的是操作数本身,而不是布尔值。例如,"a" and "b"
返回 "b"
,"" or "b"
返回 "b"
。
比较运算符
Python的比较运算符与C++和Java类似,但增加了身份比较和成员检测。
等于 | == |
判断两值是否相等 | a == 5 → True |
不等于 | != |
判断两值是否不等 | a != 3 → True |
大于 | > |
判断左值是否大于右值 | a > 3 → True |
小于 | < |
判断左值是否小于右值 | a < 10 → True |
大于等于 | >= |
判断左值是否不小于右值 | a >= 5 → True |
小于等于 | <= |
判断左值是否不大于右值 | a <= 5 → True |
身份是 | is |
判断两对象是否为同一对象 | a is 5 → 取决于实现 |
身份不是 | is not |
判断两对象是否不为同一对象 | a is not None → True |
成员存在 | in |
判断元素是否在容器中 | 3 in [1,2,3] → True |
成员不存在 | not in |
判断元素是否不在容器中 | 4 not in [1,2,3] → True |
Python支持链式比较,如 1 < a < 10
,等价于 1 < a and a < 10
。
自增/自减与复合赋值运算符
Python没有自增自减运算符(++
/--
),但提供了复合赋值运算符。
加法赋值 | += |
a += b 等价于 a = a + b |
a += 3 → a=8 |
减法赋值 | -= |
a -= b 等价于 a = a - b |
a -= 2 → a=3 |
乘法赋值 | *= |
a *= b 等价于 a = a * b |
a *= 4 → a=20 |
除法赋值 | /= |
a /= b 等价于 a = a / b |
a /= 2 → a=2.5 |
整除赋值 | //= |
a //= b 等价于 a = a // b |
a //= 2 → a=2 |
取模赋值 | %= |
a %= b 等价于 a = a % b |
a %= 3 → a=2 |
幂赋值 | **= |
a **= b 等价于 a = a ** b |
a **= 2 → a=25 |
位运算符
Python的位运算符与C++和Java类似,仅适用于整数类型。
按位与 | & |
对应位同为1时结果为1 | a & 0b1100 → 0b1000 |
按位或 | | |
对应位有1时结果为1 | a | 0b1100 → 0b1110 |
按位异或 | ^ |
对应位不同时结果为1 | a ^ 0b1100 → 0b0110 |
按位取反 | ~ |
每一位取反(0变1,1变0) | ~a → -11 (补码表示) |
左移 | << |
左移n位,低位补0 | a << 2 → 0b101000 |
右移 | >> |
右移n位,高位补符号位 | a >> 1 → 0b0101 |
常用数学函数
Python的数学函数主要在 math
模块中提供。
根号 | math.sqrt(x) |
math.sqrt(9) (结果为 |
|
绝对值 | abs(x) 或 math.fabs(x) |
abs(-7.6) (结果为 |
|
向上取整 | math.ceil(x) |
math.ceil(-7.6) (结果为 |
|
向下取整 | math.floor(x) |
math.floor(-7.6) (结果为 |
|
四舍五入 | round(x) |
round(-7.6) (结果为 |
|
幂函数 | x ** y |
2**6 (结果为 |
当然,对于那些喜欢读用英文写的、冗杂又臭长的该死的语法细节手册的同学,你可以直接看:
- C++ : C++语法官方文档
- Java : Java语法官方文档
- Python : Python语法官方文档
例题1:牛牛学加法
题意
给定两个整数 和
,输出它们的和。
思路分析
这是一道非常基础的题目,主要考察加法运算符的使用。我们需要:
- 读取两个整数
和
- 使用加法运算符
+
计算它们的和 - 输出结果
参考代码
#include <bits/stdc++.h>
using namespace std;
int main(){
int a, b; // 定义两个整数变量a和b
cin >> a >> b; // 输入两个整数
int sum = a + b; // 使用加法运算符计算它们的和
cout << sum; // 输出结果
return 0; // 结束程序
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt(); // 定义并输入整数a
int b = scanner.nextInt(); // 定义并输入整数b
int sum = a + b; // 使用加法运算符计算它们的和
System.out.print(sum); // 输出结果
scanner.close(); // 关闭输入流
}
}
a, b = map(int, input().split()) # 读取并转换为整数
sum = a + b # 使用加法运算符计算它们的和
print(sum) # 输出结果
优先级
运算符也是有优先级的,就好比乘法、除法与加法、减法的运算顺序。为了方便理解,这里只列出前面已经介绍过的运算符的优先级,按照从高到低的顺序排列。
C++
1 | ++ -- (后缀) |
后缀自增、后缀自减 | 从左到右 |
2 | ++ -- (前缀)+ - (一元)! ~ |
前缀自增、前缀自减 正号、负号 逻辑非、按位非 |
从右到左 |
3 | * / % |
乘法、除法、取余 | 从左到右 |
4 | + - |
加法、减法 | 从左到右 |
5 | << >> |
按位左移、按位右移 | 从左到右 |
6 | < <= > >= |
小于、小于等于、大于、大于等于 | 从左到右 |
7 | == != |
等于、不等于 | 从左到右 |
8 | & |
按位与 | 从左到右 |
9 | ^ |
按位异或 | 从左到右 |
10 | | |
按位或 | 从左到右 |
11 | && |
逻辑与 | 从左到右 |
12 | || |
逻辑或 | 从左到右 |
13 | = += -= *= /= %= <<= >>= &= ^= |= |
赋值和复合赋值 | 从右到左 |
需要特别注意的是,当表达式中包含多个优先级相同的运算符时,会按照结合性的规则进行计算。例如,a + b + c
会按照从左到右的顺序计算为 (a + b) + c
,而 a = b = c
会按照从右到左的顺序计算为 a = (b = c)
。
Java
1 | ++ -- (后缀) |
后缀自增、后缀自减 | 从左到右 |
2 | ++ -- (前缀)+ - (一元)! ~ |
前缀自增、前缀自减 正号、负号 逻辑非、按位非 |
从右到左 |
3 | * / % |
乘法、除法、取余 | 从左到右 |
4 | + - |
加法、减法 | 从左到右 |
5 | << >> >>> |
按位左移、按位右移、无符号右移 | 从左到右 |
6 | < <= > >= |
小于、小于等于、大于、大于等于 | 从左到右 |
7 | == != |
等于、不等于 | 从左到右 |
8 | & |
按位与、布尔与 | 从左到右 |
9 | ^ |
按位异或、布尔异或 | 从左到右 |
10 | | |
按位或、布尔或 | 从左到右 |
11 | && |
逻辑与(短路) | 从左到右 |
12 | || |
逻辑或(短路) | 从左到右 |
13 | = += -= *= /= %= <<= >>= >>>= &= ^= |= |
赋值和复合赋值 | 从右到左 |
Java的运算符优先级与C++非常相似,主要区别在于Java增加了无符号右移运算符 >>>
,以及按位运算符 &
、^
、|
也可用于布尔值的逻辑运算。
Python
1 | ** |
幂运算 | 从右到左 |
2 | + - ~ (一元) |
正号、负号、按位非 | 从右到左 |
3 | * / // % |
乘法、除法、整除、取余 | 从左到右 |
4 | + - |
加法、减法 | 从左到右 |
5 | << >> |
按位左移、按位右移 | 从左到右 |
6 | & |
按位与 | 从左到右 |
7 | ^ |
按位异或 | 从左到右 |
8 | | |
按位或 | 从左到右 |
9 | in not in is is not < <= > >= != == |
成员测试、身份测试、比较运算 | 从左到右 |
10 | not |
逻辑非 | 从右到左 |
11 | and |
逻辑与 | 从左到右 |
12 | or |
逻辑或 | 从左到右 |
13 | = += -= *= /= //= %= **= &= |= ^= <<= >>= |
赋值和复合赋值 | 从右到左 |
Python的运算符优先级与C++和Java有一些显著的不同:
- 幂运算符
**
的优先级非常高 - 使用英文单词
and
、or
、not
作为逻辑运算符 - 增加了
in
、not in
、is
、is not
等特有的运算符 - 整除运算符
//
与普通除法/
具有相同的优先级
在实际编程中,如果表达式比较复杂,建议使用括号 ()
明确指定运算顺序,这样可以提高代码的可读性,也能避免因为记错优先级而导致的错误。例如,a + b * c
可以写成 a + (b * c)
以明确乘法先于加法执行。
当然,对于那些喜欢读用英文写的、冗杂又臭长的该死的语法细节手册的同学,你可以直接看:
- C++ : C++语法官方文档
- Java : Java语法官方文档
- Python : Python语法官方文档