1. 从一句代码说起:你真的懂算术运算符吗
我之前在带新人做代码评审时,经常看到这样的场景:一个刚工作没多久的同事写了一段循环,里面用到了 i=i++,跑出来的结果和他预期完全不一样,debug 大半天找不到原因。旁边另一个同事扫了一眼说,你把 i++ 和 ++i 搞混了吧。他一脸懵:这俩不都是加1吗?有什么区别?
这也是我写这篇博文的初衷。算术运算符是编程语言里最基础的知识点,+、-、*、/、% 大家天天用,但到了 i++ 与 ++i 这里,很多人就含糊了。说句不好听的,很多工作了两三年的开发者,遇到 i = i++ 这种写法,照样会算错。
这篇内容适合正在学编程的初学者、准备面试的求职者,以及写代码多年但想夯实基础的开发者。我会从内存执行的角度,把 i++ 和 ++i 的底层逻辑讲透,再结合实际开发中的场景和面试题,帮你彻底搞定这个知识点。尤其是最后那几道题,我建议你亲手在环境里跑一遍,比看十篇文章都管用。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算术运算符全家桶先过一遍
2.1 五种常见算术运算符
先复习一下最基础的内容。Java、C、C++ 等语言里,常见的算术运算符就五种:加法 +、减法 -、乘法 *、除法 /、取余 %。
这里最容易出问题的是除法和取余。很多新手在整数除法上栽过跟头:7 / 2 在整数类型下结果不是 3.5,而是 3。因为两个整数相除,结果还是整数,小数部分直接丢弃,不是四舍五入。而 7 % 2 得到的是余数 1,% 只看余数不看商。
另外,取余运算在负数场景下也有讲究。比如 -7 % 2,在 Java 里结果是 -1,因为 Java 取余结果的符号和被除数保持一致。这一点在 C 语言里行为可能不同,C 标准只规定了 (a / b) * b + a % b 等于 a,但具体符号在不同编译器版本下可能不一样,写跨平台代码时要格外小心。
2.2 自增自减运算符的特殊地位
除了这五种,还有一种特殊的算术运算:自增 ++ 和自减 --。它俩是单目运算符,只操作一个操作数,作用就是给变量加1或减1。
++ 放在变量的左边叫前自增,放在变量右边叫后自增。前自增 ++i 是先让变量加1,再把加完后的值拿去用;后自增 i++ 是先把当前值拿去用,然后再让变量加1。
听上去很简单对不对?但很多人到了复杂表达式里就乱了。别急,我在后面会用内存执行的角度重新讲一遍,保证你听完不再犯迷糊。
3. i++ 与 ++i 的核心差异:从内存执行角度讲透
3.1 一条反编译命令看清本质
先给你一个最直观的方法:把代码编译成字节码,看看底层到底做了什么。
我用 Java 写了两个方法,然后通过 javap -c 命令反编译。这里不贴完整字节码,只讲关键结论:
java复制public static void testPost() {
int i = 0;
int a = i++;
}
public static void testPre() {
int i = 0;
int a = ++i;
}
在字节码层面,i++ 会先把变量当前值压入操作数栈,然后再对局部变量做加1。而 ++i 会先对局部变量加1,再把加完后的值压入栈。
这就解释了那个经典现象:int a = i++ 这条语句里,a 拿到的是 i 加1之前的值;int a = ++i 里,a 拿到的是加1之后的值。
3.2 用一个生活类比理解前后缀
我经常拿“发红包”给新人打比方。
i++ 像是先把你钱包里的钱数拍照留存,然后再往钱包里塞100块。你拍照时留下的金额是老金额,但钱包实际已经变多了。
++i 像是先往钱包里塞100块,再拍照。照片上的金额是新的,钱包也确实是新的。
赋值操作 int a = i++ 就好比把“照片”交给 a。你照片上是旧金额,所
