第四章-表达式相关

本文详细阐述了C++编程语言中的左值和右值的概念,强调了它们在表达式中的使用区别。文章讨论了运算符的优先级和求值顺序,特别是复合语句中可能存在的数据冒险问题。还提到了赋值运算、递增递减运算符、sizeof运算符以及各种类型的类型转换规则,包括隐式转换和显式转换如static_cast、const_cast和reinterpret_cast的使用场景。
摘要由CSDN通过智能技术生成

表达式

  • 左值和右值
    当一个对象被用作右值时,用的是对象的值(内容);被用作左值时,用的是对象的身份(在内存中的位置)

    在需要右值的地方可以用左值替代,使用左值的内容;但是不能把右值当作左值使用

  • 优先级
    规定运算对象的组合方式,括号无视优先级

  • 求值顺序
    与优先级和结合律无关
    在一条复合语句中,如果出现多个求值表达式,同时它们会改变同一对象的状态,则它会产生未定义的行为
    f()+g()*h()+j();,没有严格的调用顺序,因此会存在类似数据冒险的情况
    如果改变了某个运算对象的值,在表达式的其他地方就不要再使用这个运算对象

  • 取余运算
    取余运算的运算对象必须是整数类型
    运算结果的符号匹配第一个数字的符号,即m%n的结果符号与 m 的符号相同

  • 逻辑运算符
    短路求值&&和||
    先求左侧运算对象的结果再求右侧运算对象的结果,当左侧结果无法确定表达式的结果时才求右侧结果
    左侧运算对象可以保证右侧运算对象求值过程的正确性和安全性,例如 先判断下标是否有效,再依下标访问对象(使用&&)

  • 关系运算符
    if(i < j < k);错误
    if(i < j && j < k);正确
    避免使用布尔字面值作为运算对象,例如if(val == true),true 会转换为 1

  • 赋值运算符
    赋值结果返回的是左侧运算对象,且是一个左值
    如果左右侧运算对象类型不同,则 右侧运算对象将转为左侧运算对象类型
    如果在一个赋值表达式的左右两边使用同一运算对象,避免出现改变该对象的做法,例如*p = toupper(*p++);

  • 递增和递减运算符
    建议使用前置版本
    如果需要用到改变前的值,则使用后置版本

  • sizeof

    1. sizeof(type),返回指定类型的大小
    2. sizeof expr,返回表达式结果类型的大小
  • 逗号运算符
    常用于普通 for 循环,需要额外变量控制循环条件的时候

  • 类型转换

    • 隐式转换

      1. 算术转换,为了保证精度
      2. 初始化时,初始值转换为变量的类型;赋值时,右侧运算对象转换为左侧运算对象的类型
      3. 整型提升
      4. 一般情况下,有符号类型转换为无符号类型(具有不定性,不建议)
      5. 数组转换为指针
      6. 指针转换
        常量 0 和字面量 nullptr 可以转换成任意指针类型
        指向任意非常量的指针能转换成void*
        指向任意对象的指针能转换成const void*
      7. 转换成常量(const)
        非常量转化为常量引用或者顶层 const 指针(通过临时量实现)
      8. 类类型定义转换
        string 对象与字符串字面量
    • 显式转换
      cast-name<type>(expr)

      1. static_cast
        不包含底层 const,例如 int 到 double 等
      2. const_cast
        去掉 const 性质(常量对象转换为非常量对象,只改变常量属性)
        例如,const char *p; char *p1 = const_cast<char *>(p)
      3. reinterpret_cast
        不建议使用,例如 int *char *
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值