[C++ Primer CH04]第4章 表达式(笔记)

来源:互联网 发布:火箭勇士 知乎 编辑:程序博客网 时间:2024/06/06 12:55

小结:

C++语言提供了一套丰富的运算符,并定义了这些运算符作用于内置类型的运算对象时所执行的操作。此外,C++语言还支持运算符重载的机制,允许我们自己定义运算符作用于类类型时的含义。第14章将介绍如何定义作用于用户类型的运算符。

对于含有超过一个运算符的表达式,要想理解其含义关键要理解优先级、结合律和求值顺序。每个运算符都有其对应的优先级和结合律,优先级规定了复合表达式中运算符组合的方式,结合律则说明当运算符的优先级一样时应该如何组合。

大多数运算符并不明确规定运算对象的求值顺序:编译器有权自由选择先对左侧运算对象求值还是先对右侧运算对象求值。一般来说,运算对象的求值顺序对表达式的最终结果没有影响。但是,如果两个运算对象指向同一个对象而且其中一个改变了对象的值,就会导致程序出现不易发现的严重缺陷。

最后一点,运算对象经常从原始类型自动转换成某种关联的类型。例如,表达式中的小整形会自动提升成大整形。无论内置类型还是类类型都涉及类型转换的问题。如果需要,我们还可以显示地进行强制类型转换。


笔记:

当一个对象被用作右值得时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存的位置)。


以下两条经验准则对书写复合表达式有益:

1.拿不准的时候最好用括号来强制让表达式的组合关系符合程序逻辑的要求。

2.如果改变了某个运算对象的值,在表达式的其他地方不要再使用这个运算对象。


C++11新标准则规定商一律向0取整(即直接切除小数部分)。


进行比较运算时除非比较的对象是布尔类型,否则不要使用布尔字面值true和false作为运算对象。


除非必须,否则不用递增运算符的后置版本。愿意很简单,前置版本的递增运算符避免了不必要的工作,它把值加1后直接返回改变了运算对象。


简洁可以成为一种美德

形如*pbeg++的表达式一开始可能不太容易理解,但其实这是一种被广泛使用的、有效的写法。当对这种形式熟悉之后,书写

cout<<*iter++<<endl;

要比书写下面的等价语句更简洁,也更少出错

cout<<*iter<<endl;

++iter;


如果一条子表达式改变了某个运算对象的值,另一条子表达式又要使用该值的话,运算对象的求值顺序就很关键了。


如果一个运算对象是无符号类型、另外一个运算对象是带符号类型,而且其中的无符号类型不小于带符号类型,那么带符号的运算对象转换成无符号的。


当需要把一个较大的算数类型赋值给较小的类型时,static_cast非常有用。此时,强制类型转换告诉程序的读者和编译器;我们知道并且不在乎潜在的精读损失。


避免强制类型转换。


FAQ(Frequently Asked Questions):

Q1:算数表达式产生未定义结果的原因是?

A1:1.一部分数学性质本身:例如除数是0的情况;2.另外一部分则源于计算机的特点:例如溢出,当计算的结果超出该类型所能表示的范围时就会溢出。

原创粉丝点击