• C++Primer 第四章 表达式


    //1.当我们对运算符进行重载的时候,其包括运算对象的类型和返回值的类型都是由该运算符定义的,但是运算对象的个数和优先级,结合律都是不能改变的
    
    //2.当一个对象被用作右值的时候,用的是对象的值(内容)。当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。
    
    //3.复合表达式:是指含有两个或多个运算符的表达式。求复合表达式的值需要首先将运算符和运算对象合理的组合在一起。优先级和结合律决定了运算对象的组合方式。
    //  括号无视普通的组合规则,在表达式中括号括起来的部分被当做一个单元来求值,然后再与其他部分按照优先级组合。
    //  优先级规定了运算对象的组合方式,但没有说明运算符对象按照说明顺序求值。对于没有指定执行顺序的运算符来说,如果表达式指向并修改了同一个对象,将引发错误,并产生未定义的行为。
    //  一条形如f() + g() * h() + j()的表达式中,优先级规定g()和h()的返回值相乘。结合律规定f()的返回值先与相乘结果执行加法再与j()的返回值相加,但是对于这四个函数的调用顺序是未定义的。
    //  如果改变了某个运算对象的值,在表达式的其他地方不要继续使用这个运算对象,否则将导致未定义行为。这个规定有一个例外:当改变运算对象的子表达式本身就是另一个子表达式的运算对象时,上述规则无效。
    //  比如在表达式*++iter;中,递增运算符改变了iter的值,iter的值(已经被改变)又是解引用运算符的运算对象,此时求值顺序不会有问题。因为递增运算必须先求值然后才轮到解引用运算符。    
        int f0(){return 0;};
        int f1(){return 0;};
        int value = f0() + f1();    //f0()和f1()的调用肯定在执行+前调用,但是无法知道到底是f0()先调用还是f1()先调用。若f0()和f1()修改了同一个对象,那么value值是为定义的。
    //  有4种运算符是规定了执行顺序的: 
    //  && 先求左侧对象的值,只有当左侧对象为真,才求右侧对象的值。
    //  || 先求左侧对象的值,只有当左侧对象为假,才求右侧对象的值。
    //  cmd? expl : exp2 首先求cmd的值,若为真则继续求exp1的值,若为假则求exp2的值。
    //  , 先求左侧表达式的值,然后抛弃求值结果,再求右侧表达式的值,真正的求值结果为右侧表达式的值。
    
    //4.在表达式求值前,小整数类型(bool, char, unsigned char, short, unsigned short)的运算对象被提升为较大的整数类型(一般为int)。
    
    //5.溢出的问题:数据溢出是一种未定义行为,其结果是不可预知的,在不同的机器上表现不同。
        char value0 = 500;    //本机的溢出方式:500即0x1f4,由于value0是char类型,本机器又是小端模式,所以先存储低位,高位被抛弃,所以value0在内存中为0xf4,即244,再次发生溢出,所以value0的值为-(256-244) 即-12
    
    //6.关系运算符(< <= > >= == !=)返回类型为bool。形如 a < b < c;是将a < b的结果与c进行比较,若c是一个大于1的值,那么这个表达式恒为true。
    
    //7.++ 和 -- 其前置版本将其对象本身作为左值返回,但是其后置版本则将对象的原始值的副本作为右值返回。
    
    //8.条件运算符:当其两个表达式都是左值或者能转换成同一种左值类型的时候,返回左值。否则返回右值。条件运算符的优先级很低,就比赋值运算符高一级。
    
    //9.sizeof:
    //    返回一个表达式或者一个类型名字所占字节数
    //    sizeof并不会实际计算其运算对象的值
    //    满足右结合律
    //    对引用类型执行sizeof会得到被引用对象所占空间大小
    //    对数组执行sizeof将得到整个数组所占空间大小
    //    对vector或者string等执行sizeof只返回该类型固定部分的大小,不会计算对象中的元素占有的空间
    //    返回值为常量表达式
    
    //10.逗号运算符:首先求左侧的值,然后丢弃求值结果,返回右侧表达式的值,如果右侧表达式是左值,其返回也是左值,否则为右值
    
    //11.发生隐式类型转换的地方:
    //   在大多数表达式中,比int类型小的整形先转为较大的整数类型
    //   在条件中,非布尔类型转为布尔类型
    //   在初始化和赋值的过程中,右侧表达式转为左侧运算对象的类型
    //   如果算数类型或关系运算的的运算对象有多种类型,需要转为同一类型(运算符的运算对象将转化为最宽的类型)。C++不会将不同类型的对象进行算术操作,而是先根据类型转换规则将运算对象的类型同一后再求值。
    //   函数调用时
    //   在大多数用到数组的表达式中,数组会转化为指向数组首元素的指针。函数也会执行类似转换
    //   
        int value1 = 1.2 + 2;    //value1 = 3 求值过程为将2转为double类型与1.2相加,让后将结果3.2赋值给int类型
    
    //12.运算符优先级与结合律:
        /*
            第一级:
            ::      全局作用域      左结合
            ::      类作用域       左结合
            ::      命名空间作用域    左结合
    
            第二级:
            .       成员选择       左结合
            ->      成员选择       左结合
            []      下标         左结合
            ()      函数调用       左结合
            ()      类型构造       左结合
    
            第三级:
            ++      后置递增运算符    右结合
            --      后置递减运算符    右结合
            typeid    类型         右结合
            typeid    运行时类型      右结合
            explicit cast    类型转换      右结合        static_cast const_cast, reinterpret_cast, dynamic_cast
    
            第四级:
            ++      前置递增运算        右结合
            --      前置递减运算        右结合
            ~       位取反        右结合
            !       逻辑非        右结合
            -       一元负号       右结合
            +       一元正号       右结合
            *       解引用         右结合
            &       取地址        右结合
            ()      类型转换           右结合
            sizeof     对象大小           右结合        sizeof value;
            sizeof     类型大小           右结合        sizeof(int);
            sizeof...  参数包大小        右结合
            new     创建对象       右结合
            new[]     创建数组       右结合
            delete    释放对象       右结合
            delete[]  释放数组       右结合
            noexcept  能否抛出异常     右结合
    
            第五级:
            ->*     指向成员选择的指针    左结合        ptr->*p
            .*         指向成员选择的指针    左结合        ptr.*p
    
            第六级:
            *         乘法                左结合
            /         除法                左结合
            %         取余                左结合
    
            第七级:
            +         加法                左结合
            -         减法                左结合
    
            第八级:
            <<        左移位            左结合
            >>        右移位            左结合
    
            第九级:
            <        小于               左结合
            >        大于               左结合
            <=       小于等于            左结合
            >=       大于等于            左结合
            
            第十级:
            ==       相等              左结合
            !=       不相等            左结合
    
            第十一级:
            &        位与                左结合
    
            第十二级:
            ^        位异或            左结合
    
            第十三级:
            |        位或                左结合
    
            第十四级:
            &&       逻辑与            左结合
            
            第十五级:
            ||       逻辑或            左结合
    
            第十六级:
            ? :    条件              右结合
    
            第十七级:
            =                        右结合
            *=
            /=
            %=
            +=
            -=
            <<=
            >>=
            &=
            |=
            ^=
    
            第十八级:
            throw    抛出异常          右结合
    
            第十九级:
            ,        逗号             左结合
            */
  • 相关阅读:
    【有奖互动】3D内容平台开版啦,参与互动话题赢超值京东卡!
    HarmonyOS开发竟如此简单,九岁小朋友也能轻松上手
    HMS Core 5.3.0版本发布公告
    Web页面如何进行可视化埋点(二)
    在鸿蒙中实现类似瀑布流效果
    手把手教你快应用接入微信H5网页支付
    Scrcpy投屏真机到电脑 并集成DevEco真机调试 Mac系统下
    【软通动力】HarmonyOS三方件开发指南(6)-ActiveOhos_sqlite组件
    Web页面如何进行可视化埋点(一)
    HMS Core Insights第三期直播预告—— 当我们在谈论App的时候,我们还可以谈论什么?
  • 原文地址:https://www.cnblogs.com/szn409/p/5521265.html
Copyright © 2020-2023  润新知