表达式

表达式就是一个或多个操作数的组合,且能产生一个结果。最简单的表达式是一个单个变量或字面常量。

一些基本概念:

  • 操作符的优先级和结合性: 这个概念比较简单。

  • 操作数的转换: 转换的规则比较复杂;但一般都符合我们预期。比如,我们会把整数转成浮点数,但不会把指针类型转成浮点 数。还有,小的整型(bool, char, short)会扩展为更大的整型(如int)。

  • 操作符的重载: 给予现有操作符其它含义。

  • 左值(Lvalue)和右值(Rvalue): C++的每个表达式要么是rvalue,要么就是lvalue。这名字来自于C语言:lvalue能在赋值语句的左边, 但是rvalue不能放在左边。

在C++,这种区别更简单。lvalue表达式返回一个对象或函数。但是,有些lvalue是const对象,不能放在赋值语句的 左边。粗略地讲,我们使用右值时,我们使用的对象的值(内容);使用左值时,使用的是对象的标识(在内存的位置)。

一个重要的规则是(除了一个例外,以后会讲!!),需要右值的地方可以使用左值;但需要左值的地方不能使用右值。 当使用左值代替右值时,对象的内容(它的值)会被使用。

表达式解析的顺序

优先级指示了操作符如何结合;但没有告诉我们操作符解析的顺序。大多时候,这个顺序并不重要:

int i = f1() * f2();

这里的f1()和f2()先后调用并不重要。

对没有指明解析顺序的操作符,让表达式去修改同一对象是错误的。因为其顺序是未定义的。比如<<就是未定义操作符的解析顺序:

int i = 0;
cout << i << " " << ++i; // 未定义

有四个操作符保证了解析顺序,

  • 逻辑与&&,保证左边先解析;且仅当左边为真时,右边才解析
  • 逻辑或||
  • 条件?:
  • 逗号,

关于算术

bool b = true;
bool b2 = -b;

上面的b2还是true。因为对bool加个负号,先变成int;-1不是0,即true。

取模的%必须是整形

doubel dval = 2.2;
6 % dval; // error