C++ Primer 学习笔记(四)——表达式

来源:互联网 发布:淘宝策划工资多少 编辑:程序博客网 时间:2024/05/21 19:47

简要记一下本章自己认为重要的知识点

一、知识点

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的指针已经发生了移动(可能已经指向了这段内存的中间某个位置),没有指向动态分配空间的起始位置。