• 前++和后++引发的血案


    前++和后++引发的血案~~!!

     作者:宋桓公 
    出处:http://www.cnblogs.com/douzi2/ 
    如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

    先看一段奇葩代码:

    复制代码
    int main(void)
    {
    int x = 4;
    int y;
    = (x++);
    printf("hello world. y = %d. ", y);
     
    = 4;
    = (x++)+(x++);
    printf("hello world. y = %d. ", y);
     
     x = 4;
    = (x++)+(x++)+(x++);
    printf("hello world. y = %d. ", y);
     
     x = 4;
    = (x++)+(x++)+(x++)+(x++);
    printf("hello world. y = %d. ", y);
     
    = 4;
    = (++x);
    printf("hello world. y = %d. ", y);
     
    = 4;
    = (++x)+(++x);
    printf("hello world. y = %d. ", y);
     
     x = 4;
    = (++x)+(++x)+(++x);
    printf("hello world. y = %d. ", y);
     
     
    = 4;
    = (++x)+(++x)+(++x)+(++x);
    printf("hello world. y = %d. ", y);
    return 0;
         
    }
    复制代码

    而在VS2012(windows运行环境)的测试结果为:

    复制代码
    \后++
    
    y = 4.
    
    y = 8.   //4+4
    
    y = 12. //4+4+4
    
    y = 16. //4+4+4+4
    
    \前++
    
    y = 5.   
    
    y = 12. //6+6
    
    y = 21. //7+7+7
    
    y = 32. //8+8+8+8
    复制代码

      

    在Ubuntu上测试的结果为:

    复制代码
    //后++
    
    y = 4.
    
    y = 9.   //4+5
    
    y =15.  //4+5+6
    
    y = 22. //4+5+6+7
    
    //前++
    
    y = 5.
    
    y = 12. //6+6
    
    y = 19. //6+6+7
    
    y = 27. //6+6+7+8
    复制代码

    对应windows上的测试结果都比较好理解:

    1、对于后++而言,在赋值之前x不会递增,所以每次多一个x++不过是多一个4的累加而已。

    2、对于前++而言,在赋值前x已经递增,所以每次多一个x所对应内存的值都被提高1,最后再相加。

    所以出现了出现了6*2  7*3  8*4的结果。

     

    对于linux上的测试结果就不太容易想明白:

    1、对于后++而言第二就和windows的结果不一样了,这是因为linux用了产生中间变量的方式。

    如:y = (x++)+(x++);被分成了多步:1)tmp = x;  x = x + 1;2) tmp1 = x;  x = x + 1;  3)y  = tmp + tmp1;

    1)中tem等于4,并递增了x;2)中tmp1就等4了也递增了x;3)中就等到结果4+5=9

    当(x++)递增到三个时也是一样分析,只不过会多一个中间变量tmp2.

    2、对于前++,第三个和windows的结果不同了,也是产生了中间变量的缘故:

    如:y = (++x)+(++x)+(++x); 被分成了多步:

    1)tmp = (++x)+(++x);  2)y = tmp  + (++x);

    从而y = 6+6+7

    再如:y = (++x)+(++x)+(++x); 被分成了多步:

    1)tmp = (++x)+(++x);  2)tmp1 = tmp  + (++x);  3)y =  tmp1 + (++x);

    从而y = 6+6+7+8

    这里可能唯一让人困惑的是为什么(++x)+(++x)中间没有产生中间变量?而(x++)+(x++)却产生了中间变量?

    我猜想是因为前++应为是先递增后赋值,所以直接是x = x+1所以也就没有中间变量的产生,而作为最前面的

    两个(++x)与‘+’作用产生一个表达式:(++x)+(++x),这个表达式赋值给一个中间变量在与后面的表达式依次作用。

    总结:

       1、对于vs的编译器,在一条语句中,没有产生多余的中间变量,而ubuntu中因为产生了中间的变量。

    所以后++时ubuntu对x的内存空间有更多的操作,而前++时vs对x的内存空间有更多的操作。导致了结果的不一致。

       2、得知了第一点之后,我们应该注意在一条语句中,不要对一个变量进行多次的操作,因为你不知道编译器,对这条语句将产生多少个中间变量,而引发血案~~

  • 相关阅读:
    PDF转换程序之比较
    从两件事看老外
    Windows的启动过程
    80后的回复
    吴裕雄天生自然Spring Boot排序与分页查询
    吴裕雄天生自然Spring Boot@Query和@Modifying注解
    吴裕雄天生自然Spring BootSpring Data JPA的事务支持
    吴裕雄天生自然Spring BootSpring Boot整合Redis
    吴裕雄天生自然Spring BootSpring Boot整合MyBatis
    吴裕雄天生自然Spring Boot安装Redis
  • 原文地址:https://www.cnblogs.com/MrListening/p/5504907.html
Copyright © 2020-2023  润新知