C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)

文章目录

  • 引入
  • 左值与右值
  • 类型转换
    • 隐式类型转换
    • 显式类型转换

引入

C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第1张图片
表达式由一个或多个操作数组成,可以求值,并返回值的结果。
操作符只能接受某些类型的操作数,并不能接受全部类型的操作数。
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第2张图片
一个操作符,可以接受左值或者右值。但是有些情况下,操作符只能接受左值
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第3张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第4张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第5张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第6张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第7张图片
也有从右往左算的,比如++a. --b等,~ ! *a,&a 等等。
可以通过小括号,改变优先级顺序。
相同优先级的操作符,要么是左到右,要么是右到左。必须要这样的rules。
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第8张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第9张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第10张图片

左值与右值

C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第11张图片
左值left-value和右值right-value是针对赋值语句的等号来说的。
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第12张图片
上述是c语言的定义。
但是到了cpp,就称为:左值也不一定放在=左边,右值也可能放在=左边。
所有的划分,都是针对表达式的,不是针对对象或者数值的。

C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第13张图片
glvalue-泛左值:是一个表达式,这个表达式的求值结果可以确定一个对象、位域(某个字节的具体位置,一个bit),函数。

C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第14张图片
prvalue-纯右值:与glvalue对应,作为某个运算符的操作数,或者void表达式(一个void的函数)
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第15张图片
3是字面值,不是一个对象,所以在这里是一个纯右值。老师这里说3在底层没有一个块内存对应它。但是我的理解是,3是有开辟内存的,只是这个内存只存了字面值,而没有对象。或者指针等。

xvalue-亡值:将亡值。代表其资源能够被重新使用的泛左值。
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第16张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第17张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第18张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第19张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第20张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第21张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第22张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第23张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第24张图片
左值会产生T的引用。
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第25张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第26张图片
T&&右值引用,上面我写错了。

类型转换

C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第27张图片

隐式类型转换

C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第28张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第29张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第30张图片

显式类型转换

int main()
{
    3 + 0.5;
    static_cast<double>(3) + 0.5; // int 3 转换成 double 类型
}

C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第31张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第32张图片

int main()
{
    cout << (3 / 4) << endl; // 0
    cout << (3 / 4.0) << endl; // 0/75
    int x = 3;
    int y = 4;
    cout << (x / y) << endl; // 0
    cout << (x / static_cast<double>(y)) << endl; // 0.75

}

C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第33张图片
dynamic_cast是唯一一个在运行期进行的转换。
static_cast在编译器就弄好了,所以效率更高,但是运行时,可能出错。
const_cast,会改变变量的常量型。
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第34张图片

int main()
{
    const int x = 3;
    cout << static_cast<int>(x) << endl; // const int转成int时可以的,但是const int*不行
    const int* y;
    cout << static_cast<int*>(y) << endl; // static_cast from 'const int *' to 'int *' is not allowed
    const int* z;
    cout << const_cast<int*>(z) << endl; // 0x0, 使用const_cast是可以的
}
int main()
{
    int x = 3;
    const int& ref = x;
    int& ref2 = const_cast<int&>(ref); // 用const_cast对ref去const
    ref2 = 4;
    cout << ref << endl; // 4
    cout << ref2 << endl; // 4
    cout << x << endl; // 4
}

int main()
{
    const int x = 3; // 加了一个const
    const int& ref = x;
    int& ref2 = const_cast<int&>(ref); 
    ref2 = 4;
    cout << ref << endl; // 4 
    cout << ref2 << endl; // 4
    cout << x << endl; // 3 编译器不同,输出不同,不做保证,行为不确定
}

reinterpret cast
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第35张图片
强行将原内存重新解释。
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第36张图片
ptr2每次的值都不同,因为将一个int强行解释成double。另外int和double站的内存不同。
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第37张图片
c类型的转换
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第38张图片
C++ 基础与深度分析 Chapter4 表达式基础与详述(引入、左值右值、类型转换)_第39张图片
显示类型的转换都是有风险的。尽量不要用。

你可能感兴趣的:(C++,c++,开发语言)