Txing

欢迎来到 | 伽蓝之堂

0%

CPP Programming | Chapter 4:表达式

Chapter 4 表达式

表达式基础

  • 由1到多个操作数组成,可以求值并通常返回求值结果

    • 最基本的表达式:变量、字面值
    • 通常包含操作符/运算符
  • 操作符特性

    • 接收几个操作数(一元、二元、三元)
    • 操作数的类型-类型转换
    • 操作数是左值还是右值
    • 结果的类型
    • 结果是左值还是右值
    • 优先级与结合性(cpp-reference),可用小括号修改运算顺序
    • 操作符的重载——不改变操作数个数、优先级和结合性
  • 操作数求值的不确定性

    • fun(x=x+1,x=x+1) // 两个参数的执行先后不确定
  • glvalue:(泛左值)标识一个对象、位或函数

  • prvalue:(纯右值)用于初始化对象或作为操作数

  • xvalue:(亡值)表示其资源可以被重新使用

  • 分类方式:

    1
    2
    3
    4
    5
            expression
    / \
    glvalue rvalue
    / \ / \
    lvalue xvalue prvalue
  • C++中左值不一定能放在等号左边,右值可能放在等号左边;

  • 再论decltype

    • prvalue -> type:若表达式值类别为纯右值,则decltype产生T
    • lvalue -> type&:若表达式值类别为左值,则decltype产生T&
    • xvalue -> type&&:若表达式的值类别为亡值,则decltype产生T&&
  • 类型转换

    • 隐式转换:

      • 自动发生
      • 实际上是有限长度的转型序列
      • implicit conversion
    • 显式转换:

      • 显式引入的转换

      • static_cast

        • static_cast<double>(3) + 0.5; // 把3转换为double编译期执行
      • const_cast 可以改变const类型对象

      • dynamic_cast 运行期执行

      • reinterpret_cast 强行重新解释对象存储空间,对象值可能改变(存储格式不同)

      • C形式的类型转换

        • ```C++ (double)3;
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41

          - 自动以以下顺序尝试转换对象:`const_cast -> static_cast -> static_cast(带扩展)后随const_cast -> reinterpret_cast -> reinterpret_cast后随const_cast`

          ### 算数操作符

          - 三个优先级
          - +, - (一元,正负)
          - *, /, %
          - +, - (二元)
          - 均为左结合的,从左开始计算
          - 操作数和结果均为算数类型的右值,但加减法和正号可接收指针
          - 一元+操作符会产生integral promotion,例如short 转为int
          - 整数相除会产生整数,舍弃小数点后的部分
          - 求余 `%` 只能接收整数类型的操作数,**结果的符号与第一个操作数相同**

          ### 逻辑与关系操作符

          - 逻辑操作符:

          - !
          - &&
          - ||

          - 关系操作符接收算数或指针类型操作数;

          - 逻辑操作符接收可转换为bool值的操作数;

          - 除逻辑非外,其它操作符都是左结合的

          - 逻辑与、逻辑或具有短路特性,(A && B),如果A为假,则不判断B

          - 逻辑与优先级 > 逻辑或 (a || b && c) 等价于 (a || (b && c))

          - 不能写连续的不等于

          - ```c++
          auto res = (a <=> b) // a>b返回值大于0;a<b返回值小于0;a=b返回值等于0;
          if (res > 0){
          }else if (res < 0){
          }else if(res == 0){
          }

位操作符

  • ```c++
    // 按位非操作 & // 按位与操作 ^ // 按位异或操作 | // 按位或操作
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

    - 没有短路机制

    - 注意整数的符号与位操作的相关影响

    - integral promotion 会根据整数的符号影响其结果
    - 右移保持符号,但左移不能保证

    ### 赋值操作符

    - 赋值操作是右结合的;

    - 求值结果为左操作数;

    - 区分=和==

    - 复合赋值运算符

    - ```c++
    +=
    -=
    *=
    /=
    ^=

自增与自减运算符

  •   ++
      --
  • 分为前缀和后缀情况

  • 操作数为左值;前缀时返回左值;后缀时返回右值;

  • 建议使用前缀形式

表达式详述-其它操作符

  • 成员访问操作符:.和->
    • ->等价于(*)
    • .的左操作数是左值或右值,返回左值或右值 xvalue
    • ._>的左操作数指针,返回左值
  • 条件操作符
    • 唯一的三元操作符true ? 3 : 5;//问号前面是true时,判断第一个表达式是否为真,并返回表达式结果;问号前是false时,判断第二个表达式是否为真,并返回表达式结果
    • 接收一个可转换为bool的表达式与两个类型相同的表达式,只有一个表达式会被求值
    • 第二个和第三个表达式类型需要一致
    • 如果表达式均是左值,那么就返回左值,否则返回右值
    • 右结合
  • 逗号操作符
    • 确保操作数会被从左向右求值
    • 求值结果为右操作数
    • 左结合
  • sizeof操作符
    • 操作数可以使一个类型或一个表达式
    • 并不会实际求值,而是返回相应的尺寸
  • 其它操作符
    • 域解析操作符::
    • 函数调用操作符()
    • 索引操作符[]
    • 抛出异常操作符throw
    • ...