简要记一下本章自己认为重要的知识点
一、知识点
1、除了特殊用法外,表达式的结果为右值,可以读取此值,但是不允许对它进行赋值。
2、记住:程序不应该依赖机器相关的行为。有以下几种操作,其结果取决于机器:
(1)除法(/)和求模(%)操作,如果只有一个操作数为负数,这两种操作的结果取决于机器;求模结果的符号也取决于机器,而出发操作的值则是负数(或零),具体结果取决于机器。
(2)如果操作数为负数,则位操作符如何处理其操作数的符号依赖于机器。因此,对于位操作符,强烈建议使用unsigned整型操作数。
3、逻辑与和逻辑或操作符,“短路求值”,总是先计算其左操作数,然后再计算右操作数。
4、bitset优于整型数据的低级直接位操作。
5、二元操作符及移位操作符都是左结合(从左向右结合)的,而赋值操作符具有右结合特性,当表达式含有多个赋值操作符时,从右向左结合。
6、自增、自减操作符的后置形式,操作后产生操作数原来的、未修改的值作为表达式的结果,对此结果处理完毕后,再加减1。
注意:只有在必要时才使用后置操作符。原因:因为前置操作需要做的工作更少,只需加1后返回加1后的结果即可。而后置操作符则必须先保存操作数原来的值,以便返回未加1之前的值作为操作的结果。
以下两段代码等价:
cout << *iter++ << endl;
cout << *iter << endl;
++iter;
原因在于,后自增操作的优先级高于解引用操作。第一种写法更加简洁。 简洁即是美。
7、求值顺序。&&、|| 、条件(?:)和逗号操作符规定了操作数的计算顺序,除此之外,其他操作符并未指定其操作数的求值顺序。例如,f1() * f2()。无法确定是先调用f1还是先调用f2。如果一个子表达式修改了另一个子表达式的操作数,则操作数的求解次序就变得相当重要。注意以下两点:
(1)如果有怀疑,则在表达式上按程序逻辑要求使用圆括号强制操作数的组合;
(2)如果要修改操作数的值,则不要再同一个语句的其他地方使用该操作数。如果必须使用改变的值,则把该表达式分割成两个独立语句:在一个语句中改变该操作数的值,再在下一个语句中使用它。
8、强烈建议避免使用强制类型转换,不依赖强制类型转换也能写出很好的C++程序来。使用const_cast总是预示着设计缺陷,设计合理的系统应不需要使用强制转换抛弃const特性。
二、sizeof操作符
1、其作用是返回一个对象或类型名的长度,返回值的类型为size_t,长度单位是字节。
2、sizeof表达式的结果是编译时常量。
3、使用sizeof的结果部分地依赖所涉及的类型:
(1)对char类型或值为char类型的表达式做sizeof操作保证得1;
(2)对引用类型做sizeof操作将返回存放此引用类型对象所需的内存空间的大小;
(3)对指针做sizeof操作将返回存放指针所需的内存大小;注意,如果要获取该指针所指向的对象的大小,则必须对该指针进行解引用操作。
(4)对数组名做sizeof操作等效于将其元素类型做sizeof操作的结果乘上该数组元素的个数。返回的是整个数组在内存中的存储长度。
4、利用sizeof获得数组元素的个数:
int sz = sizeof(ia) / sizeof(*ia); //ia is an array.
三、new和delete表达式
1、动态创建的对象与在函数内定义的变量初始化方式相同(内置类型的对象无初始化)。使用中,在动态创建对象时,最好总是对它做初始化。
2、在delete之后,立即将指针置为0(NULL),表明此指针不再指向任何对象。执行语句 delete p; 之后,p变为悬垂指针,尽管p没有定义,但仍然存放了它之前所指向对象的地址,但该对象已经不存在。悬垂指针很可能导致程序错误。
3、有四种常见的程序错误都与动态内存分配有关:
(1)删除指向动态分配内存的指针失败,”内存泄漏“;
(2)读写已删除的对象。如果删除指针所指向的对象之后,将指针置为0值(NULL),则比较容易检查出这类错误;
(3)对同一个内存空间使用两次delete表达式;
(4)所要delete的指针已经发生了移动(可能已经指向了这段内存的中间某个位置),没有指向动态分配空间的起始位置。