拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

用 Go 彻底搞懂算术运算符优先级(Precedence):从表达式求值到括号技巧

用 Go 彻底搞懂算术运算符优先级(Precedence):从表达式求值到括号技巧
  • 示例工程
  • 教程

【免费下载链接】learngo

❤️ 1000+ Hand-Crafted Go Examples, Exercises, and Quizzes. 🚀 Learn Go by fixing 1000+ tiny programs.

项目地址:https://gitcode.com/gh_mirrors/le/learngo
点击查看免费下载

导读

运算符优先级(Operator Precedence)决定了5 - 2 * 5 + 7这类表达式到底先算哪一步、结果是多少,是 Go 学习者最容易踩坑的基础知识之一。本文以 learngo 仓库中 运算符优先级问答题 的四道经典题目为主线,结合仓库内完整的可运行示例代码,逐一拆解优先级、结合性、括号改写与浮点/整数混合运算的完整规则。读完本文,你将能快速心算任何由*、/、%、+、-、一元负号与括号组成的 Go 算术表达式,并掌握用括号安全改写复杂公式的实战技巧。


一、优先级是什么:乘除先算,加减后算

在 Go 中,算术运算符按优先级分层,优先级高的先执行。对本文涉及的算术运算符,规则很简单:

  • 一元运算符(如负号-x)优先级最高;
  • 乘法类运算符*、/、%次之;
  • 加法类运算符+、-最低。

也就是说,遇到没有括号的表达式时,Go 会先做乘、除、取余,再做加、减。这直接决定了5 - 2 * 5 + 7的计算路径:

  1. 先算乘法:2 * 5 = 10;
  2. 再从左到右做加减:5 - 10 + 7 = 2。

仓库中的示例 03-precedence/01/main.go 用可运行的代码演示了这一过程:

fmt.Println( 2+2*4/2, 2+((2*4)/2), // 括号显式标出实际计算顺序:先 * 后 / )

两个表达式输出相同结果,因为2+2*4/2中*与/优先级相同,且都高于+,等价于2+((2*4)/2)。

二、原题逐解:四道优先级测验全解析

问答题 02-precedence.md 用四道层层递进的题目,覆盖了优先级、结合性与括号三大知识点。这里完整还原每题的计算过程。

题 1:5 - 2 * 5 + 7→ 结果2

  • 优先级规则:*先于-、+。
  • 计算过程:5 - (2*5) + 7→5 - 10 + 7→2。
  • 干扰项分析:22是把加法全部先算的错误结果;-19是把减法先于乘法的错误结果;36、-12均为不同错误顺序下的产物。

题 2:5 - (2 * 5) + 7→ 结果2

加上括号后,乘法2 * 5被显式括起来,但括号内本来就是优先级最高的部分,所以结果与题 1 完全一致,仍为2。原题提示指出:该表达式等价于5 + (2 * 5) + 7在数值上的另一种书写方式(即先算2*5=10,再做5-10+7)。

题 3:5 - 2 * (5 + 7)→ 结果-19

这里括号改变了计算顺序:(5 + 7)优先计算,然后乘法在减法之前执行:

  1. 5 + 7 = 12
  2. 2 * 12 = 24
  3. 5 - 24 = -19

这正是"括号可以覆盖默认优先级"的经典示范:同样的数字,仅仅改变括号位置,结果就从2变成了-19。

题 4:5. - (2 * 5 + 7)→ 结果-12.0

注意题干是5.(带小数点的浮点数),而非整数5。计算过程:

  1. 2 * 5 = 10
  2. 10 + 7 = 17
  3. 5. - 17 = -12.0

原题特别指出:只要表达式中出现浮点数与整数的混合运算,结果就一定是浮点数。因此-12(整数写法)是错误的,-12.0才是正确答案。

三、同级运算符的结合性:从左到右

当优先级相同时,Go 按从左到右的结合性求值。仓库示例 03-precedence/01/main.go 同时演示了这一点:

fmt.Println( 1+4-2, (1+4)-2, // 等价:+ 和 - 同级,从左到右 )

而 03-precedence/02/main.go 用变量展示了*与/的从左到右结合,以及括号如何改变顺序:

n, m := 1, 5 fmt.Println(2 + 1*m/n) fmt.Println(2 + ((1 * m) / n)) // 实际顺序:先 1*m,再 /n // 用括号强制改变顺序 fmt.Println(((2 + 1) * m) / n)

同一组数字,2 + 1*m/n与((2+1) * m) / n的结果完全不同——前者等价于2 + ((1*5)/1) = 7,后者是(3*5)/1 = 15。这就是括号的威力。

四、括号的实战价值:华氏度转换公式

为什么括号不只是应付考试?看仓库示例 03-precedence/04/main.go,它用括号修正了一个典型的"公式陷阱":

celsius := 35. // 错误公式:9*celsius + 160 / 5 // 正确公式:(9*celsius + 160) / 5 fahrenheit := (9*celsius + 160) / 5 fmt.Printf("%g ºC is %g ºF\n", celsius, fahrenheit)

若不使用括号,9*celsius + 160 / 5会按优先级先算160/5,再算乘法与加法,得到完全错误的温度值。而(9*celsius + 160) / 5保证了"分子整体"先求和、再整体除以 5。任何涉及公式移植的代码(如单位换算、物理计算、面积计算)都该养成"拿不准就加括号"的习惯。

03-precedence/03/main.go 的注释还给出了一个完整的推演示范,可以自行运行体会:

// 1 + 5 - 3*10/2 的计算顺序: // 3 * 10 = 30 // 30 / 2 = 15 // 1 + 5 = 6 // 6 - 15 = -9 // // 用括号改写为 (1 + 5 - 3) * (10 / 2) 后, // 先算 (1+5-3),再算 (10/2),结果完全不同

五、浮点陷阱:优先级之外的精度问题

题 4 揭示了"浮点数参与运算则结果为浮点数"的规则,这与问答题 01-arithmetic-operators.md 中的内容互相印证:

  • var degree float64 = 10 / 4的结果是2而不是2.5,因为整数除法会丢弃小数部分;
  • 而var degree float64 = 3. / 2的结果是1.5,因为3.使整个表达式成为浮点运算;
  • x := 5 * 2.中x的类型是float64,同理x := 5 * -(2)中x的类型是int(全是整数)。

在此基础上还需警惕:浮点数本身存在精度误差。仓库示例 03-float-inaccuracy/01/main.go 用%.60f打印出1.0/10.0累加 10 次后的真实值,误差清晰可见。结合优先级与类型推导,才能写出结果符合预期的数值运算代码。

六、动手实践:优先级改写练习

仓库在 exercises/03-precedence/main.go 提供了一份"只用括号改变优先级、让每个表达式输出目标值"的练习,参考答案在 exercises/03-precedence/solution/main.go:

原表达式目标输出括号改写(参考答案)
10 + 5 - 5 - 102010 + 5 - (5 - 10)
-10 + 0.5 - 1 + 5.5-16-10 + 0.5 - (1 + 5.5)
5 + 10*2 - 5-255 + 10*(2-5)
0.5*2 - 10.50.5 * (2 - 1)
3 + 1/2*10 + 424(3+1)/2*10 + 4
10 / 2 * 10 % 71510 / 2 * (10 % 7)
100 / 5 / 240100 / (5. / 2)

建议先自行在 main.go 上尝试,再对照参考答案逐行推演。注意最后一行:100 / (5. / 2)中把5.写成浮点数后,5./2 = 2.5,100/2.5 = 40——若不这样做,100/5/2按整数除法从左到右得到的是10/2 = 5。它同时考察了优先级、结合性与浮点类型三个知识点,是整组练习中最有价值的一题。

七、小结:一张表记住 Go 算术优先级

优先级运算符结合性说明
最高一元-(负号)、+—作用于单个操作数
高*、/、%从左到右乘法、除法、取余
低+、-从左到右加法、减法

三条核心结论:

  1. 无括号时:先一元、再乘除取余、最后加减;同级从左到右;
  2. 有括号时:括号内最先计算,括号可以安全覆盖默认优先级,公式移植时"拿不准就加括号";
  3. 类型跟随:表达式中只要出现浮点字面量(如5.、3.),结果就是浮点类型;整数除法丢弃小数部分。

掌握了优先级与括号,就能读懂仓库中任何一行算术代码,也能在编写单位换算、几何计算等公式类程序时避免隐蔽的逻辑错误。

  • 示例工程
  • 教程

【免费下载链接】learngo

❤️ 1000+ Hand-Crafted Go Examples, Exercises, and Quizzes. 🚀 Learn Go by fixing 1000+ tiny programs.

项目地址:https://gitcode.com/gh_mirrors/le/learngo
点击查看免费下载

相关推荐

上一篇:Telegraf 实践部署:把指标采集、转换、写入跑稳的完整路径
下一篇:如何用AntiMicroX解决PC游戏手柄适配难题:5分钟快速上手终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表