• (六)、i++ 与 ++i 的区别


    一、概念问题

    i++:先使用i的值,然后再执行i = i + 1;

    public class test{
        public static void main(String[] args) {
            int a = 0;
            int b = 0;
            b = a ++; 
            System.out.println(a);
            System.out.println(b);
        }
    }

    首先,我们先把a=0这个值拿来赋值给b,即此时b=0;而此时a的值已经经过自增变为了1。

    执行顺序

    (1) j = i;

    (2) i = i + 1;

    ++i:先执行i = i + 1,然后使用i; 

    public class test{
        public static void main(String[] args) {
            int a = 0;
            int b = 0;
            b = ++ a; 
            System.out.println(a);
            System.out.println(b);
        }
    }

    首先,我们将a = 0这个值先自增为a = 1,然后再将a = 1 赋值给b,此时b=1;

    执行顺序

    (1) i = i + 1;

    (2) 将(1)所得的值赋值给等号右边

    (3) 把右边给左边

    二、面试精选

    第一题

    public class test{
        public static void main(String[] args) {
            int a = 0;
            for (int i = 0; i < 99; i++){
                a = a++;
            }
            System.out.println(a);
        }
    }

    第二题

    public class test{
        public static void main(String[] args) {
            int b = 0;
            for (int i = 0; i < 99; i++){
                b = ++b;
            }
            System.out.println(b);
        }
    }

    第三题

    public class test{
        public static void main(String[] args) {
            int a = 0;
            int b = 0;
            for (int i = 0; i < 99; i++){
                a = a ++;
                b = a ++;
            }
            System.out.println(a);
            System.out.println(b);
        }
    }

    三、性能区别

    首先我们看下for循环的执行顺序

    for(A;B;C)
    {
       D;
    }

    1.进入循环条件A; //只是进入的时候执行

    2.执行B;  //条件为真才执行D,不然就跳出for循环

    3.执行D;  

    4.执行C;

    5.再回到第2步开始执行。

    如下面实例:

    i++

    public class test{
        public static void main(String[] args) {
            for (int i = 0; i < 10; i++){
                System.out.println(i);
            }
        }
    }
    
    等同于
    
    public class test{
        public static void main(String[] args) {
            for (int i = 0; i < 10; ){
                System.out.println(i);
                i ++;
            }
        }
    }

    ++i

    public class test{
        public static void main(String[] args) {
            for (int i = 0; i < 10; ++ i){
                System.out.println(i);
            }
        }
    }
    
    等同于
    
    public class test{
        public static void main(String[] args) {
            for (int i = 0; i < 10; ){
                System.out.println(i);
                ++ i
            }
        }
    }

    上面两个实例的结果均为

    证明了i++ 和 ++i的作用是一样的

    但是,在性能方面,它俩还是有区别的

    我们先来看两者执行过程

    i++

    function () {
        tmp = i;
        i = tmp + 1;
        return tmp;
    }

    ++i

    function () {
        i = i + 1;
        return i;
    }

    结论:i++由于是在使用当前值之后再+1,所以会需要一个临时变量来转储,而++则直接+1,不存在这样的问题,也就是说i++语句是需要一个临时变量取存储返回自增前的值,而++i不需要。

    对于两者的执行效率,接着往下看,网上有两种结果:

    一种结论是执行相同的次数,++i的效率要优于i++的效率;

    另一种结论是在没有编译器优化的情况下,++i更好。优化过后两者都一样,看起来似乎喜欢怎样写都无所谓了。 但是如果这里的i不是int而是迭代器,那么++在前和在后就会有所不同,使用++i将会有切实的更高的效率。虽然int情况下没多少区别,但为了语法上的统一,最好一律改用++i这种形式。   所以,建议在这种地方一律改用++i的形式。

    以上的结论,总之改用++i的形式就得了。

    四、结论测试

    1.for循环执行100次的时候

    //使用 i++
    public class test{
        public static void main(String[] args) {
            int c = 0;
            long st = System.nanoTime();
            for (int i = 0; i < 100; i++){
                c = c + i;
            }
            long et = System.nanoTime();
            System.out.println("c=" + c);
            System.out.println("times:" + (et - st));
        }
    }

    //使用 ++i
    public class test{
        public static void main(String[] args) {
            int c = 0;
            long st = System.nanoTime();
            for (int i = 0; i < 100; ++i){
                c = c + i;
            }
            long et = System.nanoTime();
            System.out.println("c=" + c);
            System.out.println("times:" + (et - st));
        }
    }

    2.for循环执行1000次的时候

    //使用 i++
    public class test{
        public static void main(String[] args) {
            int c = 0;
            long st = System.nanoTime();
            for (int i = 0; i < 1000; i++){
                c = c + i;
            }
            long et = System.nanoTime();
            System.out.println("c=" + c);
            System.out.println("times:" + (et - st));
        }
    }

    //使用 ++i
    public class test{
        public static void main(String[] args) {
            int c = 0;
            long st = System.nanoTime();
            for (int i = 0; i < 1000; ++i){
                c = c + i;
            }
            long et = System.nanoTime();
            System.out.println("c=" + c);
            System.out.println("times:" + (et - st));
        }
    }

    3.for循环执行10000次的时候

    //使用 i++
    public class test{
        public static void main(String[] args) {
            int c = 0;
            long st = System.nanoTime();
            for (int i = 0; i < 10000; i++){
                c = c + i;
            }
            long et = System.nanoTime();
            System.out.println("c=" + c);
            System.out.println("times:" + (et - st));
        }
    }

     

    //使用 ++i
    public class test{
        public static void main(String[] args) {
            int c = 0;
            long st = System.nanoTime();
            for (int i = 0; i < 10000; ++i){
                c = c + i;
            }
            long et = System.nanoTime();
            System.out.println("c=" + c);
            System.out.println("times:" + (et - st));
        }
    }

    结论:注意本人测试的时间都是纳秒(因为毫秒结果输入是0),而且比较的结果几乎没有影响,所以在此本人认为这两者的效率我更赞同结论二,在int情况下是没有什么区别的,但还是建议改用++i的形式。

    很想高飞,但我不能;不想天空,剩我一人。
  • 相关阅读:
    【HDU3721】枚举+最长路
    满足要求的最长上升子序列(nlogn)
    Flask入门 表单Flask-wtf form原生 Bootstrap渲染(七)
    Flask入门之模板导入与块宏(六)
    Flask入门模板过滤器与测试器(五)
    Flask入门模板Jinja2语法与函数(四)
    Flask入门flask-script 蓝本 钩子函数(三)
    Flask入门request session cookie(二)
    Flask入门 flask结构 url_for 重定向(一)
    Django问卷调查项目思路流程
  • 原文地址:https://www.cnblogs.com/lixiansheng/p/11299727.html
Copyright © 2020-2023  润新知