[C++ Primer Note3] 表达式
2018-11-18 本文已影响0人
梦中睡觉的巴子
表达式由一个或多个运算对象(operand)组成,对表达式求值将得到一个结果。字面值和变量是最简单的表达式,其结果就是字面值和变量的值。
- C++语言定义了运算符作用于内置类型和复合类型的运算对象时所执行的操作。当运算符作用于类类型的运算对象时,用户可以自行定义其含义,称之为重载运算符。IO库的>>和<<运算符以及string对象,vector对象和迭代器使用的运算符都是重载的运算符。
- 复合表达式是指有两个或多个运算符的表达式。求复合表达式的值需要将运算符和运算对象合理地组合在一起,优先级和结合律决定了运算对象组合的方式。也就是决定了表达式中每个运算符对应的运算对象来自表达式的哪一部分。
- 优先级规定了运算对象的组合方式,但是没有说明运算对象按照什么顺序求值。比如:
int i=f1()*f2();
int i=0;
cout<<i<<" "<<++i<<endl;
我们无法知道f1和f2之间的调用顺序,同时也无法知道是先求++i的值还是先求i的值,这样的行为是未定义的,不可预知的。
- 如果改变了某个运算对象的值,在表达式的其他地方不要再使用这个运算对象。除非改变运算对象的子表达式本身就是另外一个子表达式的运算对象。
- 进行比较运算时除非比较的对象是布尔类型,否则不要使用布尔字面值true和false作为运算对象。
- 赋值运算符满足右结合律
- 除非必须,否则不用自增自减运算符的后置版本,因为后置版本需要将原始值存储下来以便返回。
- 形如*pbeg++的表达式是一种被广泛使用且有效的写法,表示先移动指针/迭代器,再取原来指向的对象。
- 解引用运算符*的优先级低于点运算符。
- sizeof运算符(这是一个关键字)返回一条表达式或一个类型名字所占的字节数。sizeof运算符满足右结合律,其所得的值是一个size_t类型的常量表达式,运算符的运算对象有两种形式:
- sizeof (type)
- sizeof expr
对数组执行sizeof运算得到整个数组所占空间的大小,等价于对数组中所有元素各执行一次sizeof运算并将所得结果求和。注意,sizeof运算不会把数组转换成指针来处理。
所以可以用数组的大小除以单个元素的大小得到数组中元素的个数:
constexpr size_t sz=sizeof(ia)/sizeof(*ia);
sizeof的返回值是一个常量表达式,所以我们可以用sizeof的结果声明数组维度。
- 对于算术隐式转换来说,可以简单地理解为往更大的类型转换。
- 在大多数用到数组的表达式中,数组自动转换成指向数组首元素的指针。当数组被用作decltype关键字参数,或者作为取地址符(&),sizeof及typeid等运算符的运算对象时,上述转换不会发生。
- 类类型能定义由编译器自动执行的转换,比如C风格字符串转换成string,在条件部分读入istream等。
- 一个命名的强制类型转换具有以下形式:cast-name<type>(expression);
- static_cast:任何具有明确定义的类型转换,只要不包含底层const
- const_cast: 只能改变运算对象的底层const
- reinterpret_cast:为运算对象的位模式提供重新解释(比如把int *解释成char *)
- 避免使用强制类型转换
- 在早期版本的C++语言中,显式地进行强制类型转换包含两种形式:
- type (expr); 函数形式的
- (type) expr; C语言风格的