第5章:表达式

转载请注明原文出处:http://blog.csdn.net/roddick621

以下的知识点全部都是来自于C++ Primer 第四版,如果需要详细了解的话,可以查看原版的书籍。


表达式由一个或多个操作数(operand)通过操作符(operator)组合而成,而每个表达式都会产生一个结果(result)。C++提供了一元操作符(unary operator),二元操作符(binary operator)和三元操作符(ternary operator)


1.算术操作符:

优先级越高越在前
操作数功   能用   法
+一元正号+ expr
-一元负号- expr
*乘法expr * expr
/除法expr / expr
%求余expr % expr
+加法expr + expr
-减法expr - expr

2.关系操作符和逻辑操作符。

以下操作符都产生bool值
操作符功  能用   法
!逻辑非! expr
<小于expr < expr
<=小于等于expr <= expr
>大于expr > expr
>=大于等于expr >= expr
==等于expr == expr
!=不等expr  != expr
&&逻辑与expr && expr
||逻辑或expr || expr
不应该串联使用关系操作符。


3.位操作符。

位操作符使用整型的操作数。它会讲整数操作数视为二进制位的集合,为每一位提供检验和设置的功能。另外,这类操作符还可以用bitset类型的操作数。

位操作符
操作符功  能用  法
~位求反~ expr
<<左移expr1 << expr2
>>右移expr1 >> expr2
&位与expr1 & expr2
^位异或expr1 ^ expr2
|位或expr1 | expr2

位操作符操纵的整数的类型可以是有符号的,也可以是无符号的。如果操作数是负数,则位操作符如何处理其操作数的符号依赖于机器。

左移操作符(<<)在右边插入0以补充空位。

右移操作符(<<)如果其操作数是符号的数,则从左边开始插入0;如果操作数是有符号数,则插入符号位的副本或者0值。

以为操作的右操作数不可以是负数,而且必须是严格小于左操作数的值,否则,操作的效果未定义。


4.赋值操作符。

赋值操作符的左操作数必须是非const的左值。赋值表达式的值是左操作数的值,其结果的类型为左操作数的类型。通常,赋值操作讲其右操作数的值赋给左操作数,然而当左右操作数的类型不同时,该操作实现的类型转换可能会修改被赋的值。

  1. 复制操作的右结合性
  2. 赋值操作具有低优先级
  3. 复合赋值操作符


5.自增和自减操作符

自增(++)和自减(--)提供了前置和后置两种形式。

1.后置操作符返回未加1的值。(使用完变来那个的当前值,然后再加1)。

2.单个表达式中组合使用解引用和自增操作。

vector<int>::iterator iter=ivec.begin();
while (iter != ivec.end())
    cout << *iter++ <<endl;
//*iter++等效于*(iter++)。子表达式iter++是iter加1,然后返回iter原值的副本作为该表达式的结果,因为这里姐操作*的操作数是iter未加1前的副本。

6.箭头操作符。

可用箭头操作符(->)来获取类类型对象的成员。但是调用该操作符的必须是一个指向类类型对象的指针。


7.条件操作符。

条件操作符是C++中唯一的三元操作符。语法格式为: cond ? expr1 : expr2 ;

避免条件操作符的深度嵌套

在输出表达式中使用条件操作符。条件才操作符的优先级向当低,因为最好严格的使用圆括号把条件操作符括起来。


8.sizeof操作符

sizeof操作符的作用是返回一个对象或类型名的长度,返回值的类型为size_t。使用sizeof的结果部分地依赖所涉及的类型:

  • 对char类型或值为char类型的表达式做sizeof操作保证得1。
  • 对引用类型做sizeof操作返回存放次类型对象所需的内存大小空间。
  • 对指针做sizeof操作将返回指针所需的内存大小。
  • 对数组做sizeof操作等效于将对其元素类型做sizeof操作的结果乘上数组元素的个数。

9.逗号操作符

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


10.符合表达式的值

含有两个或更多操作符的表达式成为符合表达式,操作数和操作符的结合方式决定了整个表达式的值。结合方式取决于

1.优先级

2.结合性

3.求值顺序


11.new和delete表达式

动态创建对象时,只需指定其数据类型,而不必为对象命名,new表达式返回的指向新创建对象的指针。

1.动态创建对象的初始化

int *pi = new int(1024) // pi指向地址中存的值是1024

C++使用直接初始化语法规则初始化动态创建的对象。如果是提供了初值,new表达式分配到所需的内存后,用给定的初值初始化内存空间。

2.动态创建对象的默认初始化。

对于类类型的对象,用该类的默认构造函数初始化,而内置内省的对象则无初始化。

3.耗尽内存

4.撤销动态创建的对象

动态创建的对象用完后,程序员必须显式地将对象占用的内存返回给自由存储区。C++ 提供了delete表达式释放指针对指向的地址空间。 eg : delete pi;

5.零指针的删除

如果指针的值为0,那么在其上做delete操作是合法的。e.g. : int *pi =0; delete ip;

6.在delete之后,重设指针的值。

删除指针后,该这真变成悬垂指针。悬垂指针指向曾经存放对象的内存,但该对象已经不存在了。

7.const对象的动态分配和回收。

const * pci = new const int(1024); //创建也初始化一个const对象。
与其他常来那个一样,动态创建的const对象必须在创建时初始化,并且已经初始化,其值就不能再修改。对于类类型的const动态对象,如果该类提供了默认的构造函数,则此对象可隐式初始化,内置类型或为提供默认构造函数的对象必须显式初始化。

8.删除const对象。

尽管程序员不可以改变const对象的值,但是可以撤销对象本身。如同其他动态对象一样,const动态对象也是使用删除指针来释放的:

delete pci; // delete a const object

12 类型转换

如果两个类型之间可以相互切换,则称两个类型相关。

有些转换规则又编译器自动执行的,成为隐式类型转换。为了理解隐式类型转换,我们需要知道他们在什么时候发生,以及可能出现什么类型的转换。

12.1 何时发生隐式类型转换。

编译器在必要时将类型转换规则应用到内置类型和类类型的对象上。

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

2.用做调教的表达式转换为bool类型

3.用以表达式初始化某个变量,或将以表达式复制给某个变量,则该表达式被转换为该变量的类型。


12.2 算术转换

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

最简单的转换为整型提升:对于比int小的整型,包括char,signed char,unsigned char,short和unsigned short,如果该类型的所有值能够包容在int内,他们就会提升为int,否则他们将会提升为unsigned int。如果bool值提升为int,则false为0,ture为1。


12.3 其他隐式转换

1.指针转换:

使用数组时,大多数情况下数组都对自动转换为指向第一个元素的指针。C++还提供了另外两种指针转换:指向任意数据类型的指针都可以转换为void *类型;整型数值0可以转换为任意指针类型。

2.转换为bool类型:

算术值和指针值都可以转换为bool类型。如果指针或算术值为0,则其bool值为false,而其他值则为true。

3.算术类型月bool类型的转换:

可将算术类型转换为bool类型,bool类型也可以转换为int类型。讲算术类型转换为bool类型,0转换为false,而其他值转换为true。将bool对象转换为算术类型时,true变成1,而false则为0。

4.转换与枚举类型

C++自动将枚举类型的对象和枚举成员转换为整型,其转换结果可用于任何要求使用整型数值的地方。

5.转换为const对象。

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

6.由标准库类型定义的转换。


12.4 显示转换

显式转换也成为强制类型转换(cast),包括以下列名字命名的强制类型转换操作符:static_case , dynamic_case , const_cast 和 reinterpret_case


12.5 何时需要强制类型转换

1.因为要覆盖通常的标准转换。

2.可能存在多种转换事,需要算则一种特定的类型转换。


12.6 命名的强制类型转换

格式为case-name<type> (expression);   case-name为以上的4个方法,type为转换的目标类型,expression则是被强制转换的值。

1.dynamic_cast

dynamic_case支持运行事识别指针或引用对指向的对象。对dynamic_case的引用将在18.2节中进行。

2.const_cast

讲转换掉表达式的const性质。除了添加和删除const特性,用const_cast符来执行其他任何类型转换,都会引起编译错误。

3.static_cast

编译器隐式执行的任何类型转换都可以由static_cast显示完成。当需要将一个较大的算术类型赋值给较小的类型时,使用强制转换非常有用。还可以通过static_cast来找回存放在void *指针中的值。

4.reinterpret_cast

reinterpret_cast通常为操作数的位模式提供较低层次的重新解解释。(本质上依赖于机器)





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值