自增运算符是困扰 C 语言与 Java 语言初学者的一大难点,在我最初学习 C 语言时,一直无法理解 i++ 与 ++i 的区别。
几年的语言学习,特别是对 Java 语言的学习,对一些基本知识点有了更深入的理解,现在我来谈谈 i++ 与 ++i 的区别与联系。
注意:这里只讲解 i++ 与 ++i ,i- - 与 - -i 可以类比过来
i++ 与 ++i 介绍i++ 与 ++i 都是自增运算符,i++ 有时被称作后加运算符,++i 被称作前加运算符。
顾名思义,后加运算符就是先赋值,在自增长 1,而前加运算符是先自增长 1,然后在赋值。
Java 中的 i++ 与 ++i通常,i++ 与 ++i 都是出现在循环里面,每循环一次 i 的值都自增长 1 。
/** * @author kyyee * */ public class Test { @org.junit.Test public void test() { int i; i = 0; System.out.println("the result of i++:" + i++ + ",the current value of i:" + i);// 12 i = 0; System.out.println("the result of ++i:" + ++i + ",the current value of i:" + i);// 14 } }这段代码输出的结果会是什么呢?
i++ 被称为后加是有道理的,12 行代码输出的结果为:the result of i++:0,the current value of i:1
++i 被称为前加,14 行代码输出的结果为:the result of ++i:1,the current value of i:1
借助数学公式来理解 i++ 和 ++i
i++a = i++;
=> a = i ; i += 1;
a = ++i;
=> i += 1; a = i;
这就是为什么代码里打印 i++ 为 0,而打印 ++i 为 1 的原因。
结语在实际应用中,i++ 和 ++i 并没有区别,最终实现的效果都是自增长1。
具体的,当我们在 for 循环里使用 i++ 与 ++i 时,不同的编译器会对它们进行优化,这也就是为什么有的时候当一段 C 代码直接翻译成 Java 代码后会出现错误的原因。
注意:++i 是左值,而 i++ 不是。
附注:讨论 i++ 与 ++i 的效率 /** * @author kyyee * */ public class Test { public static void main(String[] args) { long startTime1 = System.nanoTime(); for (int i = 0; i < 1000000; i++) { } System.out.println("i++ time(ms):" + Long.toString((System.nanoTime() - startTime1) / 1000)); System.out.println("i++ time(s):" + Long.toString((System.nanoTime() - startTime1) / 1000 / 1000)); long startTime2 = System.nanoTime(); for (int i = 0; i < 1000000; ++i) { } System.out.println("++i time(ms):" + Long.toString((System.nanoTime() - startTime2) / 1000)); System.out.println("i++ time(s):" + Long.toString((System.nanoTime() - startTime2) / 1000 / 1000)); } }理论上,经过编译器优化后 i++ 与 ++i 的效率几乎一样,实际测试,++i 效率高于 i++。
从前面的分析过程,i++在计算过程中会多一个缓存变量保存中间值,这直接导致i++速度慢于++i。
#i++++i时间消耗(s) 5 3
时间消耗(s) 5 4
时间消耗(s) 5 4
时间消耗(s) 3 14
时间消耗(s) 8 1
时间消耗(s) 5 3
去掉不合理的 2 组数据,100 万次循环,++i 比 i++ 平均少2s,因此编程中推荐使用 ++i。