CH4
1. 表达式由一个或多个操作数(operand)构成,最简单的表达式由一个文字常量或一个对象构成。在更一般的情况下,表达式由一个或多个操作数、以及应用在这些操作数上的操作构成。
2. 应用在操作数上的操作由操作符(operator)表示。
3. 作用在一个操作数上的操作符被称为一元操作符(unary operator),比如取地址操作符(&)和解引用操作符(*);作用在两个操作数上的操作符,比如加法操作符、减法操作符,被称为二元操作符(binary operator)。
4. 当两个或两个以上的操作符被组合起来的时候,这样的表达式被称为复合表达式(compound expression)。
5. 是否能够成功地计算表达式要取决于子表达式的计算顺序。
6. 子表达式的计算顺序由操作符的优先级(precedence)和结合性(associativity)来决定。
7. 算术表达式的计算会导致不正确或未定义的值,这些情况被称为算术异常(arithmetic exception)(但是不会导致抛出实际的异常)。算术异常要归咎于算术的自然本质(比如除以0),或归咎于计算机的自然本质——比如溢出(overflow)(指结果值超出了被赋值对象的类型长度)。
8. static_cast<int> (byte_value)称为显式类型转换(explicit type conversion)或强制类型转换(cast);强制转换使编译器把一个对象(或表达式)从它当前的类型转换成程序员指定的类型。
9. 等于、关系和逻辑操作符的计算结果是布尔常量true或false。
10. 一个对象只能被初始化一次,也就是在它被定义的时候,但是在程序中可以被赋值多次。
11. 标准库提供的复数(complex)类是基于对象的类抽象的完美模型。
12. sizeof操作符的作用是返回一个对象或类型名的字节长度。
13. 系统为每个程序都提供了一个在程序执行时可用的内存池,这个可用内存池被称为程序的空闲存储区(free store)或堆(heap);运行时刻的内存分配被称为动态内存分配(dynamic memory allocation)。
14. 动态内存分配由new表达式应用在一个类型指示符(specifier)上来完成,类型指示符可以是内置类型或用户定义类型;new表达式返回指向新分配的对象的指针。
15. new表达式并不返回实际被分配的对象,而且返回这个对象的地址;对象的所有操作都通过这个地址间接来完成。
16. 当对象完成了使命时,必须显式地把对象的内存返还给空闲存储区,通过把delete表达式应用在“指向用new表达式分配的对象指针”上来做到这一点。
17. 逗号表达式是一系列由逗号分开的表达式,这些表达式从左向右计算,逗号表达式的结果是最右边表达式的值。
18. 位操作符把操作数解释成有序的位集合,这些位可能是独立的,也可能组成域(field),每个位可以含有0(off)或1(on)。
19. 如果一个对象被用作一组位或位域的离散集合,那么这样的对象称为位向量(bitvector)。位向量是一种用来记录一组项目或条件的是/否信息(有时也称为标志(flag))的紧缩方法。
20. 用整值类型表示位向量的问题在于,使用位操作符来设置、复位和测试单独的位,层次比较低,也比较复杂。
21. bitset类支持两个成员函数,它们能将bitset对象转换成其他类型:一种情况是用to_string()操作,将任意bitset对象转换成string表示;另一种情况是用to_ulong()操作,将任意bitset对象转换成unsigned long型的整数表示。
22. 操作符优先级是指复合表达式中操作符计算的顺序。操作符具有优先级和结合性。
23. 一组算术转换(arithmetic conversions)在执行算术运算前,将两个操作数转换成共同的类型;转换规则是小类型总是被提升成大类型,以防止精度损失。
24. 隐式类型转换(implicit type conversion):转换由编译器自动完成,无需程序员介入。
25. 可以通过指定显式类型转换(explicit type conversion)来禁止标准算术转换。
26. 隐式类型转换发生在下列这些典型的情况下:1)在混合类型的算术表达式中,在这种情况下最宽的数据类型成为目标转换类型,这也被称为算术转换(arithmetic conversion);2)用一种类型的表达式赋值给另一种类型的对象;3)把一个表达式传递给一个函数调用,表达式的类型与形式参数的类型不相同(目标转换类型是形式参数的类型);4)从一个函数返回一个表达式,表达式的类型与返回类型不相同(目标转换类型是函数的返回类型)。
27. 算术转换两个通用的指导原则:1)为防止精度损失,如果必要的话,类型总是被提升为较宽的类型;2)所有含有小于整型的有序类型的算术表达式在计算之前,其类型都会被转换成整型。
28. 在确定共同的目标提升类型之前,编译器将在所有小于int的整值类型上施加一个被称为整值提升(integral promotion)的过程。
29. 显式转换也被称为强制类型转换(cast),包括下列命名的强制类型转换操作符:static_cast、dynamic_cast、const_cast和reinterpret_cast。
30. 任何非const数据类型的指针都可以被赋值给void*型的指针。有时void*型的指针被称为泛型generic指针,因为它可以指向任意数据类型的指针。不存在从void*型指针到特殊类型的指针之间的自动转换。
31. 执行显式强制转换的原因:1)把void*型的指针赋值给任意显式类型;2)希望改变通常的标准转换;3)要避免出现多种转换可能的歧义情况。
32. reinterpre_cast通常对于操作数的位模式执行一个比较低层次的重新解释,它的正确性很大程度上依赖于程序员的主动管理。
33. 栈是计算机科学的一个基本数据抽象,它允许以后进先出(LIFO)的顺序嵌入和获取其中的值;栈的两个基本操作是:向栈中压入(push)一个新值以及弹出(pop)或获取最后压入的那个值;其他一些操作包括:查询栈是否满full()或空empty(),以及判断栈的长度size()——即包含多少个元素。