左值 (lvalue, locator value) :表示了一个占据内存中某个可识别的位置(也就是一个地址)的对象。
可修改左值 (modifiable lvalues) :可被赋值的左值。C99标准定义可修改左值为:可修改左值是特殊的左值,不含有数组类型、不完整类型、const 修饰的类型。如果它是 struct 或 union,它的成员都(递归地)不应含有 const 修饰的类型。
右值 (rvalue) :只存在于临时寄存器中。
除了数组、函数、不完整类型的所有左值都可以转换为右值。
int a = 1; // a 是左值
int b = 2; // b 是左值
int c = a + b; // a 和 b 被转换成右值 // + 返回右值
右值不能转换为左值。
右值可以显式地赋值给左值(不能隐式转换,右值不能使用在左值应当出现的位置)。
一元解引用操作符 ‘*’ 需要一个右值参数,但返回一个左值结果。
int arr[] = {1, 2};
int* p = &arr[0];
*(p + 1) = 10; // 正确: p + 1 是右值,但 *(p + 1) 是左值
一元取地址操作符 ‘&’ 需要一个左值参数,返回一个右值。
int var = 10;
int* bad_addr = &(var + 1); // 错误: 一元 '&' 操作符需要左值参数
int* addr = &var; // 正确: var 是左值
&var = 40; // 错误: 赋值操作的左操作数需要是左值
引用类型又叫做“左值引用”。因此,不能将一个右值赋值给(非常量的)左值引用:
std::string& sref = std::string(); // 错误: 非常量的引用 'std::string&' 错误地使用右值 'std::string` 初始化
常量的左值引用可以使用右值赋值。因为你无法通过常量的引用修改变量的值,也就不会出现修改了右值的情况。
常用:函数的参数使用常量引用接收参数,避免创建不必要的临时对象。
cv 限定符是 const 和 volatile 关键字的统称。
表示数据只读,不能被修改。
和 const 是相反的,表示数据是可变的、易变的,目的是不让 CPU 将数据缓存到寄存器,而是从原始的内存中读取。作用:改善编译器的优化能力。
cppreference.com