zoukankan      html  css  js  c++  java
  • 关于C语言的自增运算符

    昨天参加智邮普创的面试,发现自己c语言好渣啊,先就昨天的一个问题学习一下,然后这周要不停学c来面对如果还有的二面了。
    先通过一道面试题引入
    int main(void) {
    int a=3;
    int b=0;

    b=(++a)+(++a)+(++a);

    printf(” %d %d ”, a, b);

    return 0;
    }
    面试的时候以为答案是15,结果被学长问有没有在电脑上敲过,刚刚敲了一遍发现是16,然后百度了一下大概知道了是怎么计算的。++a是一个有副作用的表达式,这段代码在不同的编译器的解释也是不一样的。如果按照平常的理解,似乎是4+5+6=15,但是在gcc和vc编译下都是16,在网上发现有的人在其他编译器下敲出来是18。
    结果为16的情况是:先将变量a自增了两次,然后相加,最后再自增一次再和前面的和相加得出最后结果。

    那在我理解看,++a先自增后使用(这里的使用理解为两项相加即为使用了)。
    也就是第一个a自增后要使用,就是要和第二项相加,此时第二项也为++a,所以它也要先自增再使用(这里的使用即为与第一项求和),这时a在存储器中已经变化为5,然后需要使用,即将前两项求和结果为10,然后加最后一项,最后一项需要先自增为6再求和,答案为16。

    如果这个逻辑成立,那么a++就可以理解为先使用后自增。
    但是当我输入b=(++a)+(a++)+(a++)来证明我的理解时,如果按照上述逻辑,应该是4+4+5(即在(++a)+(a++)完成后可以算是使用了,然后a自增为5),结果应该为13,可执行后发现结果为12而不是13,那就说明a++的使用是以整个表达式为单位。

    也就是a++的先使用后自增这里的使用理解为整个表达式执行完即为使用了。我计算了b=(a++)+(a++)+(a++)结果为9,好像猜想是对的。

    最后,我结合两种情况敲入了b=(++a)+(a++)+(++a)+(++a);这样一个表达式,按照我的理解来分析这个式子:第一项a先自增为4,然后它要使用自增之后的值,也就是与第二项相加,第二项a先使用,也就是4+4=8,这个时候第二项的自增操作需要等整个表达式进行完后再进行,因为前文分析过a++的使用后自增是以表达式为单位判定的。这样继续第三项a先自增,然后使用,就是与之前计算的和相加,即5+8=13。最后一项b先自增为6再使用,即6+13=19。这时第二项的a++执行自增操作,a变为7。经过vc和dev实际验证,发现结论正确!

    这样,基本证实了在gcc编译器下自增操作符的运算规则,但是在TC编译器下,编译器对b=(++a)+(++a)+(++a)的理解为6+6+6,这里不再赘述。
    在平时使用中,是要避免使用这些带有副作用的表达式的,我也是因为面试题才研究了一下,关于c中表达式的求值顺序,我推荐阅读下面这篇文章https://bbs.csdn.net/topics/370153775

  • 相关阅读:
    Android应用安全之外部动态加载DEX文件风险
    Android应用安全之Android APP通用型拒绝服务漏洞
    利用Cydia Substrate进行Android HOOK(二)
    Apk去签名校验详解
    nginx部署前端项目的一些配置【刚入门】
    java 日期格式化 将String日期重新格式化成String型【转】
    idea导入maven项目时需要注意
    element 'dependency' cannot have character [children], because the type's content type is element-only.
    腾讯云centos7执行 systemctl status postfix.service 启动postfix服务时出现 /usr/sbin/postconf: fatal: parameter inet_interfaces: no local interface found for ::1
    redis.clients.jedis.exceptions.JedisExhaustedPoolException: Could not get a resource since the pool is exhausted
  • 原文地址:https://www.cnblogs.com/wxylyw/p/9073505.html
Copyright © 2011-2022 走看看