zoukankan      html  css  js  c++  java
  • C++表达式

    冰哥哥最近在刷笔试题,昨晚问了一个没有意义,但很有意思的一个问题:

    求输出:

    #include<iosteam>
    int main(){
         int a=10;
         a+=a-=a++;
         std::cout<<a<<std::endl;
         return 0;  
    }

    C++中,只有赋值运算符和单目运算符是右结合性,其他大部分的运算符都是左结合。

    后缀运算符的优先级很高,仅次于"::“作用域解析符(与->操作符属于同一优先级,所以不能写出a->b++这样的表达式)

    于是,上面的运算表达式可以写成:a+=a-=(a++);进一步,a+=a-=(10) a=a+1; a=a+1在某一时刻完成。

    a++会改变自身的值,进一步影响程序中其他调用a的部分。在C++中,对变量值会进行改变的表达式被称为具有修改环境的属性。所有带有修改环境属性的程序语句(包括运算表达式、函数调用等),它们修改环境的影响将在下一个顺序点被执行完毕(即语言保证这些影响:寄存器的值、内存的值、cache的值等等能够在下一次被读取前的某时刻被完成)。

    所以,要明白a+=a-=(a++)最重要的就是明确a++对其他运算符的对象:a产生的影响在什么时候完成。

    C/C++语言定义(语言的参考手册)明确定义了顺序点的概念。顺序点位于:
    1. 每个完整表达式结束时。完整表达式包括变量初始化表达式,表达式语句,return语句的表达式,以及条件、循环和switch语句的控制表达式(for头部有三个控制表达式);
    2. 运算符 &&、||、?: 和逗号运算符的第一个运算对象计算之后;
    3. 函数调用中对所有实际参数和函数名表达式(需要调用的函数也可能通过表达式描述)的求值完成之后(进入函数体之前)。

    注意前面的一句话,影响的完成是在下一个顺序点之前。a+=a-=()不会触发顺序点,也就是a++对a的影响是在什么时候完成的,我们不得而知。

    ——————————————————————————————————————————————————————————————————————————————————————

    讨论了一圈回来,我们得到的答案是此式没有答案。是啊,在真正的编写代码,写出这样的代码完全是找虐和找骂,没有正确性的保障,也没有可读取性和效率可言。

    最后在结束时,再提一个关于C++运算符的误区:

    a++ + b++

    a++和b++谁先做?不是从左到右,在C++中没有规定大多数二元运算的两个对象的计算顺序(除了&&、|| 和 ,),也没有规定函数参数和被调函数的计算顺序。

    在我们日常的程序设计中,一定不能出现依赖于修改值的先后顺序的语句,因为C/C++ 语言的规定告诉我们,任何依赖于特定计算顺序、依赖于在顺序点之间实现修改效果的表达式,其结果都没有保证。

  • 相关阅读:
    [USACO 2012 Feb B]Moo
    [Atcoder ARC124] XOR Matching 2-小思维 | 暴力
    loj数列分块入门
    2019牛客暑期多校2-Partition problem深搜
    Codeforces 1554C
    [USACO 2012 Feb G]Cow Coupons----贪心&带悔(看完稳AC)
    Codeforces 220B-Little Elephant and Array-扫描线 & 树状数组
    [AtCoder ARC098] Donation| 建图 | 树型dp
    关于幂等性以及怎么实现幂等性
    【OOM】解决思路
  • 原文地址:https://www.cnblogs.com/wangpei0522/p/3886493.html
Copyright © 2011-2022 走看看