zoukankan      html  css  js  c++  java
  • 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    抛出异常          右结合
    
            第十九级:
            ,        逗号             左结合
            */
  • 相关阅读:
    OSCP Learning Notes Buffer Overflows(3)
    OSCP Learning Notes Buffer Overflows(5)
    OSCP Learning Notes Exploit(3)
    OSCP Learning Notes Exploit(4)
    OSCP Learning Notes Exploit(1)
    OSCP Learning Notes Netcat
    OSCP Learning Notes Buffer Overflows(4)
    OSCP Learning Notes Buffer Overflows(1)
    OSCP Learning Notes Exploit(2)
    C++格式化输出 Learner
  • 原文地址:https://www.cnblogs.com/szn409/p/5521265.html
Copyright © 2011-2022 走看看