自增和自减操作符

自增(++)和自减(--)操作符为对象加1和减1操作提供了方便简短的实现方式.它们有前置或后置两种使用形式.到目前为止,我们已经使用过前自增操作,该操作使其操作数加1,操作结果是修改后(changed)的值.同理,前自减操作使其操作数减1.这两种操作符的后置形式同样对其操作数加1(或减1),但操作后产生操作数原来的、未修改的值作为表达式的结果:

int i=0,j;
j=++i;//j=1,i=1:prefix yields incremented value
j=i++;//j=1,i=2:postfix yields unincremented value

因为前置操作返回加1后的值,所以返回对象本身,这是左值.而后置操作返回的则是右值.(也就是说,前置自增是先自增,然后操作赋值之类的,而后置自增可以理解为先操作,再自增.)

--------------------------------------------------我是华丽的分割线------------------------------------------------------

建议:只有在必要时才使用后置操作符

有使用C语言背景的读者可能会觉得奇怪,为什么要在程序中使用前自增操作.道理很简单:因为前置操作需要做的工作更少,只需加1后返回加1后的结果即可.而后置操作则必须先保存操作数原来的值,以便返回未加1之前的值作为操作的结果.对于int型对象和指针,编译器可优化掉这项额外工作.但是对于更多的复杂迭代器类型,这种额外工作可能会花费更大的代价.因此,养成使用前置操作这个好习惯,就不必操心性能差异的问题.

---------------------------------------------------我是华丽的分割线-----------------------------------------------------

1.后置操作符返回未加1的值.

当我们希望在单个复合表达式中使用变量的当前值,然后再加1时,通常会使用后置的++和--操作:

vector<int> ivec;  //empty vector
int cnt=10;
//add elements 10...1 to ivec
while(cnt>0)
ivec.push_back(cnt--);  //int postfix decrement

这段程序使用了后置的--操作实现cnt减1.我们希望把cnt的值赋给vector对象的下一个元素,然后在下次迭代前cnt的值减1.如果在循环中使用前置操作,则是用cnt减1后的值创建ivec的新元素,结果是将9至0十个元素依次添加到ivec中.

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

下面的程序使用了一种非常通用的C++编程模式输出ivec的内容:

vector<int>::iterator iter=ivec.begin();
//prints 10 9 8...1
while(iter !=ivec.end())
cout<<*iter++<<endl; //iterator postfix increment

由于后自增操作的优先级高于解引用操作,因此*iter++等效于*(iter++).子表达式iter++使iter加1,然后返回iter原值的副本作为该表达式的结果.因此,解引用操作*的操作数是iter未加1前的副本.

这种用法的根据在于后自增操作返回其操作数原值(没有加1)的副本.如果返回的是加1后的值,则解引用该值将导致错误的结果:ivec的第一个元素没有输出,并企图对一个多余的元素进行解引用.

------------------------------------------------------------------------我是饥饿的分割线----------------------------------

小心:如果程序员对C++和C语言都不太熟悉,则常常会弄不清楚表达式*iter++的含义.

建议:简洁即是美

没有C语言基础的C++新手,时常会因精简的表达式而苦恼,特别是像*iter++这类令人困惑的表达式.有经验的C++程序员非常重视简练,他们更喜欢这么写:

cout<<*iter++<<endl;

而不采用下面这种冗长的等效代码:

cout<<*iter<<endl;

++iter;

对于初学C++的程序员来说,第二种形式更清晰,因为给迭代器加1和获取输出值这两个操作是分开来实现的.但是更多的C++程序员更习惯使用第一种形式.

要不断地研究类似的代码,最后达到一目了然的地步.大部分的C++程序员更喜欢使用简洁的表达式而非冗长的等效表达式.因此,C++程序员必须熟悉这种用法.而且,一旦熟悉了这类表达式,我们会发现使用起来更不容易出错.

----------------------------------------------------我是饥饿的分割线---------------------------------------------------

习题5.15 解释前自增操作和后自增操作的差别.

前自增操作和后自增操作都使其操作数加1,二者的差别在于:前自增操作将修改后操作数的值作为表达式的结果值;而后自增操作将操作数原来的、未修改的值作为表达式的结果值

习题5.16  你认为为什么C++不叫做++C?

C++之名是Rick Mascitti在1983年夏天定名的,C说明它本质上是从C语言演化而来的,"++"是C语言的自增操作符.C||语言是C语言的超集,是在C语言基础上进行的扩展(引入了new、delete等C语言中没有的操作符,增加了对面向对象程序设计的直接支持,等等),是先有C语言,再进行++,根据自增操作符前、后置形式的差别,C++表示对C语言进行扩展之后,还可以使用C语言的内容;而写成++C则表示无法再使用C的原始值了,也就是说C++不能向下兼容C了,这与实际情况不符.

习题5.17  如果输出vector内容的while循环使用前自增操作符,那会怎么样?

如果返回的是加1后的值,则解引用该值将导致错误的结果:ivec的第一个元素没有输出,并企图对一个多余的元素进行解引用

 

 

随便黏贴一段程序:

#include<iostream>
using namespace std;
void reset(int *ip)
{
 *ip=0;
 ip=NULL;
}
void main()
{
 int i=42;
 int *p=&i;
 cout<<"i:"<<*p<<'/n';
 reset(p);
 cout<<"i:"<<*p<<endl;
 p=NULL;
 cout<<"i:"<<*p<<endl;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值