zoukankan      html  css  js  c++  java
  • a++与++a的陷阱与盲区

       故事发生在2019.7.15的3.pm,正在复习数据结构题目,写了一句如下指令(以下函数运行在win10的dev编译器下面)

    #include<bits/stdc++.h>
    using namespace std;
    
    int main(void){
    	int a = 0;
    	printf("%d
    ", a++);
    //	printf("%d%d
    ", a++, ++a);
    	return 0;
    }
    

      

      发现2条语句输出不一样,你敢信?前面输出0,后面输出1,2,心态瞬间就崩了,同为a++,2次结果输出不一样!!!随后找了晗神和谢大佬,2位大佬给出的答案不一样

    晗神(centos的g++运行环境):前面是0,后面是0,1 和我一样,当场崩溃,怀疑是编译器原因)

    谢大佬:不同编译器结果不同!!!(顿悟为什么晗神和自己输出结果不一样)

     --------------------------------------------------------------- ------------------------------------------------------------------

     ----------------------------------------个人建议:后面内容没必深入了解,只要注意别将a++,a--,--a,++a一起输出就好 ------------------------

     -------------------------------------------------------------------------------------------------

    但是为什么我会输出1,2呢?

      汇编语言解释一下(以i++,--i为例)

      

    这三句汇编中执行了–操作,说明,printf函数中,两个i,先计算–i,然后计算i++,然后计算--i.
    这三句话做了一下的事情:
    1.将i从内存中取出来,然后存入到寄存器中。
    2.将寄存器中的值-1。
    3.将寄存器中减过1得值存入到内存地址中去。
    总结:前置减减,是对值做了减操作后,将其存入到原来的位置。
        简单来说:就是先-i,然后计算i++,再算--i, 也就是说(i = 0,结果会输出-1, 0)

      全部列出来:

        

    #include<bits/stdc++.h>
    using namespace std;
    
    int main(void){
    	int a = 0;
    //	printf("%d
    ", a++);			        //输出0
    //	printf("%d%d
    ", a++, ++a);		//输出1 2    
    //	printf("%d%d
    ", a++, a++);		//输出1 0  ---
    //	printf("%d%d
    ", a++, --a);		//输出-1 0 
    //	printf("%d%d
    ", a++, a--);		//输出-1 0 
    //	printf("%d%d
    ", ++a, ++a);		//输出2 2 
    //	printf("%d%d
    ", ++a, a++);		//输出2 0 ---
    //	printf("%d%d
    ", ++a, --a);		//输出0 0 
    //	printf("%d%d
    ", ++a, a--);		//输出0 0 
    
    	return 0;
    }    
    

        但是a++, a++ 与 ++a,a++输出结果不符合道理,然后看下面这篇博客

        https://blog.csdn.net/findgeneralgirl/article/details/78376834

        总结了一句话:猜测a++放的是临时变量,++a是直接计算,

                  假设a = 0

                  也就是说a++,a++这样,先将a++压栈,临时变量a + 1,然后输出a++(输出1),但是临时变量不影响后面a++的值,所以 a++依然是0

                  而对于a++,++a这样,先压栈,临时变量a + 1,然后输出a++(输出1),临时变量影响++a的值,所以++a是2

               后面运算--a,a++,--a,a--之类的也满足上面的观点

        由于不同编译器运行结果不一样,所以没事最好别把a++,++a写到一条语句里面

    拓展(湖南大学2012年研究生入学真题):

        1.a = 2,b = 3, b+=(++a)+(++a)

         分析:b += 优先级最低,最后面算,先拆2个括号a = 4,b += (4 + 4) ,b = 11

        2.i = 5, i+++i 

         分析: ++优先级比+高,所以i = 6即(i++) + i = 5 + 6 = 11,若改成(++i) + i = 6 + 6 = 12

      

        

  • 相关阅读:
    MYSQL数据库常用语句
    node.js(http协议)
    web 后端规范与思想
    linux系统下开启一个简单的web服务
    linux基础学习之软件安装以及常用命令(三)
    Vue如何使用动态刷新Echarts组件
    linux基础学习之软件安装以及常用命令
    linux基础学习
    浅谈FIle协议与Http协议及区别
    vueJs的简单入门以及基础语法
  • 原文地址:https://www.cnblogs.com/meditation5201314/p/11189877.html
Copyright © 2011-2022 走看看