C++Primer读书笔记(第五章)

第五章

5.1 算术操作符

         +,-(取正取负), *, /, %, +, -

操作符%称为“求模”或“求余”操作符。如果两个操作数为正,除法和求模的结果也都是在正数;如果都是负数,那么求模为负数;如果只有一个操作数为负数,那么求模结果取决于机器。

5.2 关系操作符和逻辑操作符

         !,<, <=, >, >=, ==, !=, &&, ||

5.3 位操作符

         ~,<<, >>, &, ^, |

         对于位操作符,由于系统不能确保如何处理其操作符的符号位,所以建立使用unsigned整型操作数。移位操作符的右操作数必须严格小于左操作数位数的值。相比于低级的直接位操作,标准库bitset类型提供的操作更加可靠。

5.4 赋值操作符

         =,+=, -=, *=, /=, %=, <<=, >>=, &=, ^=, |=

赋值表达式返回的是其左操作数的值,结果类型为其左操作数的类型,允许将多个赋值表达式写在一个表达式中。

5.5 自增和自减操作符

         只有在必要的时候才使用后置操作符,因为后置操作符处理复杂,需要先保存原值。

5.6 箭头操作符

         用于获取类类型对象的成员,对象成员用点操作符(.),类指针用箭头操作符(->)。

5.7 条件操作符

         condition? expr1 : expr2;        //优先级很低,一般都用括号括起来

         cout<< (i > j) ? i: j;             //等价于:cout<< (i > j);  cout ? i: j;

5.8 sizeof操作符

         sizeof的作用是返回一个对象或类型名的长度,返回值的类型为size_t,长度单位是字节。sizeof表达式的结果是编译时的常量。sizeof(expr);将获得该表达式结果的类型长度,但是并不计算表达式的值。所有sizeof  *p;中,p可以是一个无效地址。

5.9 逗号操作符

         逗号表达式是一组由逗号分隔的表达式,这些表达式从左向右计算,结果是最右边的表达式的值。

5.10 复合表达式操作符

         操作符的优先级,求值顺序。

5.11 new和delete表达式

         动态创建对象,需要进行初始化,未初始化的对象所关联的值是不可使用的。

         int  *pi = new int;                 //未初始化,不可直接使用

         int  *pi = new int ();              //初始化为指向int值为0的对象

         如果指针指向不是用new分配的内存地址,则在该指针上使用delete是不合法的。

         零值指针用delete删除是合法的,但是没有任何意义。

         执行delete  p;后,p变成没定义,但是仍然存放了它之前所指向对象的地址,成为悬垂指针,往往会导致程序错误。建议操作:一旦删除了指针所指向的对象,立即将指针置为0,这样就非常清楚地表明指针不再指向任何对象。

         C++允许动态创建const对象:const  int *pci = new  const  int(1024);一经初始化便不可修改,delete  pci;可撤销对象本身,达到删除指针释放内存的目的。

5.12 类型转换

5.12.1 何时发生隐式类型转换

         (1)在混合类型的表达式中,其操作数被转换为相同类型;

         (2)用作条件的表达式被转换为bool类型;

         (3)用一表达式初始化某个变量,或将一表达式赋值给某个变量,则该表达式该转换为变量的类型;

(4)函数调用是实参转换为隐参类型。

5.12.2 算术转换

         算术转换保证在执行操作之前,将二元操作符(如算术或逻辑操作符)的两个操作数转换为同一类型,并使表达式的值也具有相同的类型。

         对于包含signed和unsigned型的表达式,表达式中的signed型树脂会被转换为unsigned型。如果是signed型值是负数,就会有副作用。long和unsigned  int的转换,只要long型足够表示unsigned  int型的所有值,就将unsigned  int转换为long,否则全转换为unsigned  long型。

         char  cval;      short  sval;

         sval+ cval;                 //sval和cval同时转换为int型

5.12.3 其它隐式转换

当使用非const对象初始化const对象的引用时,系统将非const对象转换为const对象,还可将非const对象的地址(或非const指针)转换为指向相关const类型的指针。

5.12.4 显示转换

         当需要覆盖通常的转换标准时,需显示使用强制类型转换。虽然有时候确实需要强制类型转换,但是它们本质上是非常危险的。转换格式如下:

         cast-name(expression);       //cast-name为下面4者之一,type为目标类型

         (1)dynamic_cast,支持运行时,识别指针或引用所指向的对象。

         (2)const_cast,将转换掉表达式的const性质。

         const  char *pc_str;            char  *string_copy (char  *c){… };

         char  *pc = string_copy ( const_cast(pc_str) );

         (3)static_cast,可以执行任何隐式指向的类型转换。从一个较大的算术类型到一个较小的类型赋值,编译器会产生警告,使用static_cast就可以关闭警告。

         (4)reinterpret_cast,通常为操作数的位模式提供较低层次的重新解释,使用起来很危险,int  *ip;  char *pc = reinterpret_cast (ip); 那么之后,编译器就一直认为pc指向的对象是字符数组,而其实它是一个指向int类型的对象。

5.12.5 旧式强制类型转换

         type(expr);     (type) expr;

         这都类似于reinterpret_cast的效果,不提倡再使用旧式的。

你可能感兴趣的:(C/C++)