🔷 第三章 运算符与表达式
📄 一句话概括

左值(lvalue)= 有地址的"盒子",能放在 = 左边;右值(rvalue)= 临时算出来的"气球",只能读、飘在半空。判断口诀就一句:能被赋值 / 能取地址的,是左值。2 = a 为什么报错?本节给出终审裁决。

一、两个概念,一个比方

左值 lvalue 右值 rvalue
本质 占着内存的盒子 临时算出的值
有没有地址 有(能取地址) 没有(算完就散)
能不能被赋值 能 不能
出现位置 = 两边都行 只能 = 右边
比方 贴了门牌号的仓库 气球(没地方贴门牌)
int a = 5;
a        // 左值:变量是盒子
5        // 右值:字面量是气球
a + 1    // 右值:算式结果是新气球(即使 a 是盒子)
a = 10   // 整个赋值表达式的值(10)也是右值

注意最容易被忽略的一条:a + 1 虽然含有盒子 a,但算出来的结果是个新值——临时气球。所以 a + 1 = 5 报错,哪怕表达式里有变量。

二、终审裁决台:= 的左边必须是左值

编译器看到 =,第一件事就是检查左边:

a = 5;        // 过:a 是盒子
5 = a;        // 不过:气球上没地方写字
a + 1 = 5;    // 不过:算式结果是气球
a = b + 1;    // 过:左边是盒子,右边随便是啥

这就是 3.1.4 "左边必须是个盒子"的原理层:赋值的本质是"把值写进一块有地址的内存"——气球没有地址,写不进去。

术语解密:lvalue = location value(有位置/地址的值)——"左值"这个名字只是因为常在左边,本质是"有地址"。右值同理是"只能读的临时值"。

三、简单裁决法

拿到一个东西,两步判型:

  1. 它是变量名吗? → 大概率左值
  2. 它是字面量、算式结果、比较结果、函数返回值吗? → 右值

几个边界案例练手感:

表达式 判定 理由
x 左值 变量盒子
3.14 右值 字面量
x + 1 右值 临时结果
x *= 2 右值 赋值表达式的"值"是临时的
"hello" 右值 字符串字面量

为什么这门课要学它? 一是看懂报错(error: lvalue required as left operand of assignment 是新手高频错误,报错名里就有 lvalue);二是第 8 章函数返回值、将来 C++11 的移动语义都要靠这组地基——现在把"盒子 vs 气球"的直觉立起来。

四、动手 Demo:裁决台现场

#include <iostream>
using namespace std;

int main() {
    int a = 1, b = 2;
    a = 5;               // 过
    a = b + 1;           // 过
    // 5 = a;             // 取消注释:报错 lvalue required
    // a + 1 = 5;        // 取消注释:报错 lvalue required

    // 进阶冷知识(能编过,知道即可):C++ 里赋值表达式本身的结果是左值,
    // 所以 (a = b) = 9; 合法且 a 变 9——这条和 C 语言不同,别深究,体会"赋值有值"的极端形态

    cout << &a << endl;  // 取地址成功 → 左值铁证(& 是第 8 章主角,先见识)
    return 0;
}

动手方式:逐条取消注释编译,把报错原文抄进笔记——lvalue required 这个报错你这一生还会见很多次,第一次见就要认得。

30 秒实验:&a 输出一个十六进制地址(如 0x61ff08)——左值有地址的直接证据;再试 &(a + 1)——编译报错,气球取不了地址。

五、常见误区

  1. "左值就是'在左边的值'"——名字的由来,不是定义。本质是有地址。a = b 里 b 在右边,但它仍是左值。
  2. "表达式里有变量,就是左值"——a + 1 含盒子但结果是气球。看整体表达式的结果,不看零件。
  3. "常量变量 const 不能赋值,所以不是左值"——const 变量仍是左值(有地址),只是"不许写"。左值分可写和只读两种。
  4. "这概念考试才用"——lvalue required 报错、第 8 章函数返回值、C++11 移动语义全在这地基上。现在立直觉,将来省大力。
自测四问(点开对答案) 1. `x = 3` 中,x、3、整个表达式分别是什么?——x 左值、3 右值、整个赋值表达式的值(3)是右值。 2. `a + 1 = 5` 为什么错?——算式结果是临时值(气球),无地址可写,不能当 = 左边。 3. 判断左值的口诀?——能被赋值/能取地址的,是左值。 4. `2 = a` 的报错里会看到哪个词?——`lvalue`(lvalue required as left operand of assignment)。

相关笔记