Skip to content

1.10 - 表达式简介

表达式

考虑以下语句:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// five() is a function that returns the value 5
int five()
{
    return 5;
}
int main()
{
    int a{ 2 };             // initialize variable a with literal value 2
    int b{ 2 + 3 };         // initialize variable b with computed value 5
    int c{ (2 * 3) + 4 };   // initialize variable c with computed value 10
    int d{ b };             // initialize variable d with variable value 5
    int e{ five() };        // initialize variable e with function return value 5

    return 0;
}

上述各语句都定义并初始化了一个新的变量。注意上述变量的初始化值的构建,使用了不同的元素:字面量、变量、运算符和函数。然而,C++会将上述所有的形式,转换为一个单值,并用该值来完成变量的初始化。

上述初始化值之间有什么共同点呢?它们都利用了表达式。

表达式是字面量、变量、运算符和函数调用的结合体且最终可以产生一个单值。执行表达式的过程称为求值,最终生成的值则称为表达式的结果

当表达式完成求值后,表达式中的每一项(term)也都完成了求值,直到得到一个最终的单值结果。下面是一些表达式的例子,表达式后面的注释解释了它的求值方法。

1
2
3
4
5
6
7
2               // 2 是一个字面量,求值结果为 2
"Hello world!"  // "Hello world!" 是一个字面量,求值结果为字符串 "Hello world!"
x               // x 是一个变量,求值结果即 x 的值
2 + 3           // 运算符 + 将 2 和 3 相加得到 5
x = 2 + 3       // 2 + 3 求值得到 5,然后赋值给变量 x
std::cout << x  // x 求值得到 x 的值,然后将其打印到控制台界面上
five()          // 对函数 five() 的返回值求值

正如你看到的那样,字面量求值的结果就是其本身。变量求值的结果,是变量的值。虽然函数调用我们还没有介绍,但是在表达式的语境中,函数调用的求值结果是函数的返回值。运算符的求值则允许我们合并多个值并最终得到一个新值。

注意,表达式并不以分号结尾,而且也不能作为单独的元素进行编译。例如,如果你想要编译 x = 5 ,你的编译器将会保存(大多数情况下会提示你缺少分号)。实际上,表达式总是作为语句的一部分进行求值的。

例如,考虑下面这条语句:

1
int x{ 2 + 3 }; // 2 + 3 是一个表达式它不以分号结尾 -- 分号应该位于包含该表达式的语句的末尾

如果你想要深究该表达式的语法,它应该是如下这种形式:

1
type identifier { expression };

Type 可以是任何合法的类型(这里使用了int),标识符可以是任何合法的变量名(这里使用了 x)。表达式可以是任何合法的表达式(这里使用了 2+3,即两个字面量和一个运算符)。

关键信息

在 C++ 中,任何允许你使用一个单值的地方,你都可以使用一个表达式来替代,因为这个表达式最终会求值得到一个单值。

表达式语句

有些表达式本身是有其特定用途的(例如 x = 5)。但是,前面我们也说过,表达式必须是语句的一部分,那么如何才能单独地使用这些特定的表达式呢?

幸运的是,我们可以将表达式转换为一个等价的语句(称为表达式语句)。表达式语句包含一个表达式,然后紧接着一个分号。当该语句执行时,表达式就会被求值(表达式的结果会被丢弃)。

因此,我们可以将任意表达式(例如 x = 5)转换成等价的表达式语句(例如,x = 5;)并编译。

注意,我们可以编译表达式语句,但这样做有时是没有意义的(例如 2 * 3;),它的求值结果为 6,然后 6 就被丢弃了。

法则

表达式中计算得到的值会在表达式结束后被丢弃。