CC++ & Algorithm

被忽略的神奇符号:从糖果到围棋,C++里的算术运算符远不止加减乘除这么简单

写了不少年代码,我越来越觉得,初学者最容易栽跟头的地方,往往不是那些高深莫测的算法,而是最基础的算术运算符。别不信,我见过太多自以为“这谁不会”的开发者,在整数除法和取余上摔得鼻青脸肿。算术运算符看起来是小学数学,但C++里它没那么单纯。

就拿除法举例。你在纸上写“7除以2”,答案是3.5,这没问题。但如果你在C++里写7 / 2,结果会是3,不是3.5。因为两个整数相除,C++会直接舍掉小数部分——没错,它不会四舍五入,就是直接扔掉。这就是所谓的整数除法。很多初学者的第一个逻辑bug往往就出在这里,查了半天才发现是整数除法的锅。

我们来看个有意思的例子,一个三位数求各位数字之和的问题。比如输入123,要求输出1+2+3=6。这其实就是算术运算符的经典应用场景:

int x = 123;
int a = x / 100;        // 百位:123 / 100 = 1
int b = (x / 10) % 10; // 十位:123 / 10 = 12, 12 % 10 = 2
int c = x % 10;         // 个位:123 % 10 = 3

看到没有?巧妙地结合整除和取余,就可以把数字的每一位拆开。两个运算符配合使用,威力就出来了。

说到取余(也就是%,模运算),它是一个特别被低估的运算符。不只是算余数这么简单,它在编程中的地位和加减乘除一样重要:

  • 判断奇偶x % 2 == 0表示偶数,反之是奇数
  • 周期性问题:比如走格子,循环往复
  • 数字拆分:上面那个题就是绝佳例子

再来看一个更复杂的问题。围棋棋盘上的机器人寻路问题——棋盘是19×19的边框,机器人只能沿着边框移动,求最短路径。这个题表面上是个数学问题,其实是个三维立体思维的问题,但它非常巧妙地用到了绝对值和取余。

int diffX = abs(x1 - x2);
int diffY = abs(y1 - y2);
// 沿着边框走最短路径,其实就是在棋盘的四边上绕行

如果你仔细思考,这个问题其实可以抽象成:在矩形的四条边上,从一点到另一点的最短距离。这里的关键是,你需要理解边框上的两个点只能沿着边框移动,而边框的长度是固定的——这是一个把几何问题转成代数问题的典型例子。

回到取余,有个面试题我特别喜欢问:C++中7 % 3的结果是什么? 如果有人回答2,我就在心里给他打100分——正确答案就是1。7除以3得2余1,这个1就是取余的结果。别笑,真有程序员在这个问题上翻了车,混淆了“商”和“余数”的概念。

还有一道题,问哪个表达式的值等于15。这就考察你对运算符优先级和求值顺序的理解。3 * 5是15,这个简单。但如果你写10 + 5 / 2呢?先算除法得2,再加10得12,不是15。或者(10 + 5) / 2?得7.5,但因为整数除法,实际是7。这些都是坑,但一旦你理解了运算符的规律,这些坑就成了你的优势。

写代码这么多年,我对算术运算符最深的感悟是:它们是编程世界里最朴素但也是最强大的工具。从简单计算到复杂算法,处处都少不了它们的身影。

进阶学习的建议:

  1. 别只做简单的算数练习,多接触取余的妙用。判闰年、进制转换、循环队列,这些都是取余发挥威力的地方
  2. 理解运算符优先级,但不要试图背下所有规则。遇到复杂表达式,不如直接加括号,让代码更可读
  3. 重点掌握浮点运算和整数运算的区别,很多bug都源于两者混用
  4. 如果你开始学算法了,算术运算符会陪你走很远——快速幂、模运算、数论,每一步都离不开它

这篇文章对你有帮助吗?

有用 100%没用 0%

想系统学习这个知识点?查看完整知识点 →