ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

第二集,运算符的苦恼

第二集,运算符的苦恼 摘要本文以「加号失恋记」的趣味故事开篇系统讲解 Java 中的各类运算符包括算术运算符、关系运算符、逻辑运算符、位运算符、条件运算符并梳理运算符的优先级规则最后总结常见踩坑点帮助读者在写代码时避开除零、赋值与判断混淆、短路陷阱、浮点比较等易错问题。《加号失恋记》我是一枚加号业界劳模每天被拉去算钱算到手软。可今天我暗恋的等号居然牵起了乘号的手 —— 我的心从此只剩减法。一.运算符在代码的世界里运算符用不对也会让程序伤心我们熟知的 - * / % 很多运算规律和我们熟知的差不多但是也有很多我们需要注意的点不然会跑错程序。运算符定义运算符是程序中用来执行运算的符号比如加号做加法、等号做赋值、乘号*做乘法。二.算术运算符1.1 ab、a-b、a*b 按部就班地计算但是到了 a/b 时注意除数不能为零。作为大 XS 的我们还记得 a 叫什么、b 叫什么吗——被除数a/除数b 商1.2 等号在代码里叫赋值而不是判断比如 ab 和 ab 是两个概念1.3 取模符号 %当计算结果为小数时取整数。1.4 增量运算符包括 -*有人好奇为啥没有这个 /答案是这玩意存在感太低很少有人会去用其次就是如果除数为 0那么代码会报错、数据会崩溃ab 实质上是 aab其他几个同样看成这样计算1.5 自增/自减运算符自增 自减 --需要注意的是前置和后置的区别减号也一样口诀符号在后先用后加。符号在前先加后用举个例子int a 5; int b a; // 符号在后先用后加 System.out.println(b b); // 输出b 5 System.out.println(a a); // 输出a 6 int c 5; int d c; // 符号在前先加后用 System.out.println(d d); // 输出d 6 System.out.println(c c); // 输出c 6三.关系运算符关系运算符自然是两个数或者符号之间存在关系关系运算符主要有六个分别是!它们的结果都是true或者false举个例子int a 10; int b 20; System.out.println(a b : (a b)); // 输出a b : false System.out.println(a b : (a b)); // 输出a b : false System.out.println(a b : (a b)); // 输出a b : true System.out.println(a b : (a b)); // 输出a b : false System.out.println(a b : (a b)); // 输出a b : true System.out.println(a ! b : (a ! b)); // 输出a ! b : true关系运算符自然是两个数或者符号之间存在关系四.逻辑运算符逻辑运算符主要有||运算的结果为boolean类型。口诀两个真才为真||有真则为真表逻辑非。注意事项短路现象当||前一个判断条件满足为真的时候则直接短路不会判断后面的举个例子int a 10; // 第一个条件为 true直接短路不会执行后面的判断 boolean result (a 0) || (a / 0 1); System.out.println(result result); // 输出result true为了方便快速查阅下面把几类运算符的符号、作用、示例和注意事项汇总成一张对比表类型符号作用示例注意事项算术运算符、-、*、/、%进行加减乘除和取模运算a b、a / b、a % b整数除法除数不能为 0否则程序崩溃取模对负数结果不直观如 -7 % 3 结果是 -1。关系运算符、、、、、!比较两个数或表达式的大小、是否相等a b、a b结果都是 true 或 false注意 是判断相等 是赋值两者不要混淆。逻辑运算符、||、!对布尔值做与、或、非运算(a 0) (b 0) 两个真才为真|| 有真则为真 和 || 存在短路现象前一个条件能决定结果时后面的代码不会执行。位运算符、|、^、~直接对二进制位进行与、或、异或、取反运算a b、a ^ b、~a速度很快常用于底层优化、权限控制、状态标记按位与和按位或不会短路。条件运算符? :根据判断条件在两项中选一个值相当于简化的 if-else(age 18) ? 成年 : 未成年写法简洁适合简单的二选一嵌套过多会降低可读性不建议滥用。五.位运算符位运算符包括按位与按位或|按位异或^按位取反~其中按位与和按位或就不会存在短路的情况位运算是直接对二进制位进行操作的运算速度很快常用于底层优化、权限控制、状态标记等场景。下面逐个说明它们的规则按位与两个二进制位都为 1 时结果才为 1否则为 0。常用于清零、取指定位。按位或|两个二进制位只要有一个为 1结果就为 1。常用于给某位置 1、合并标记。按位异或^两个二进制位不同则结果为 1相同则为 0。常用于交换两个数、加密、切换状态。按位取反~把每个二进制位取反0 变 11 变 0。常用于取补码、快速求负数。举个例子int a 6; // 二进制110 int b 3; // 二进制011 System.out.println(a b (a b)); // 输出a b 2二进制 010 System.out.println(a | b (a | b)); // 输出a | b 7二进制 111 System.out.println(a ^ b (a ^ b)); // 输出a ^ b 5二进制 101 System.out.println(~a (~a)); // 输出~a -7按位取反后为补码六.条件运算符只有一个三目运算符格式一般为判断条件选项a选项b它相当于一个简化的 if-else 语句判断条件为真时取选项 a为假时取选项 b。举个例子int age 18; String result (age 18) ? 成年 : 未成年; System.out.println(result); // 输出成年三目运算符的优点是写法简洁适合在赋值时根据条件快速选择值缺点是嵌套过多会降低可读性所以一般只用于简单的二选一场景。七.运算符的优先级当多个运算符出现在同一个表达式里时谁先算、谁后算就由优先级决定。优先级高的先执行同级的一般从左往右依次计算。常见运算符的优先级从高到低大致如下括号优先级最高想先算谁就把它括起来。自增自减 、--单目运算优先级很高。乘除取模 *、/、%先于加减计算。加减 、-再往后。关系运算符 、、、、、!用于比较大小或是否相等。逻辑与 先于逻辑或。逻辑或 ||最后参与判断。赋值 、、-优先级最低最后执行。举个例子int result 2 3 * 4; // 先算乘法 3 * 4 12再算加法 2 12 System.out.println(result); // 输出14如果想让加法先算就用括号把加法包起来括号的优先级最高int result (2 3) * 4; // 先算括号里的 2 3 5再乘 4 System.out.println(result); // 输出20口诀括号最优先乘除先于加减赋值最后算。遇到拿不准的表达式直接加括号最稳妥既提高优先级也让代码更易读。八.运算符的坑运算符用起来虽然方便但稍不注意就会踩坑下面总结几个最常见的坑写代码时一定要留个心眼。除数为 0整数除法中除数为 0 会直接报错程序崩溃浮点数除 0 则得到 Infinity 或 NaN结果往往不是想要的。赋值 和判断 混淆写条件时少写一个等号就把判断变成了赋值程序不报错但逻辑全错这类 bug 最难排查。自增自减前置后置分不清符号在后先用后加符号在前先加后用用错会导致结果差 1。短路陷阱 和 || 有短路现象前一个条件已经能决定结果时后面的代码不会执行别把关键操作放在后面。取模对负数结果不直观-7 % 3 的结果是 -1 而不是 2不同语言规则还不一样涉及负数取模时要格外小心。浮点数比较不精确0.1 0.2 并不等于 0.3直接比较浮点数往往得到 false需要设置误差范围再比较。优先级记错比如 2 3 * 4 先算乘法逻辑与先于逻辑或赋值最后执行拿不准就加括号。举个例子看看短路和浮点数的坑// 坑1短路导致后面的代码没执行 int count 0; boolean flag (count 0) (count 0); System.out.println(count count); // 输出count 0count 根本没执行 // 坑2浮点数直接比较不相等 double x 0.1 0.2; System.out.println(x 0.3); // 输出false System.out.println(x); // 输出0.30000000000000004口诀除零必崩、等号别少写、短路要当心、浮点别直比。写运算符时多留个心眼能省下不少排查 bug 的时间。夜深了我靠在代码的角落里看着等号和乘号并肩走远心里却慢慢释然。其实我明白每个运算符都有自己的位置——等号负责赋值乘号负责放大而我加号负责把一段段零散的值拼成完整的结果。失恋的减法做完了明天醒来我依然是那个被无数表达式需要的加号继续把日子一点一点加起来。
返回列表