zoukankan      html  css  js  c++  java
  • 转:前置自增(自减)和后置自增(自减)

    第一篇:转自 http://pppboy.blog.163.com/blog/static/30203796201041014447359/

                      http://pppboy.blog.163.com/blog/static/302037962011112311822421/

    一、基本认识

    前置递增效率更高,后置式递增要拷贝一个临时对象。

    1 int b = i++; 
    2 //可以分解为一下过程:  
    3 int temp = i;  
    4 b = temp;  
    5 i = i + 1;

    n++要开辟一个变量来保存n的值并返回,然后让n这个变量中的值加 1。而++n直接把1加到n这个变量的空间中去,并返回n这个空间中的值,没有开辟任何临时空间,性能更高。

    n+=1与n=n+1在结果上是等价的。但使用复合赋值操作符+=时,直接把1加到变量n的空间中去,左操作数只计算了一次加法;而使用长表达式 n=n+1时,先要去n这个变量空间中去取值(要寻址),与1做一次加法计算,然后做一次赋值计算把结果存入到n这个空间中,这样左操作数n计算了两次。因此,n+=1的性能更高。事实上,这也是复合赋值操作符存在一个基本原因。很多人刚开始八成会困惑,为什么会存在+=,-=,*=这样的操作符,能提高程序的性能就是其中的一个原因。

    1.VC编译器优化?能前置,就别后置。(这一条应该视情形而定)

    2.养成使用前置操作符的习惯

    3.养成使用复合赋值操作符的习惯

    二、重载和句法区别

    C++规定后缀形式有一个int类型参数,当函数被调用时,编译器传递一个0做为int参数的值给该函数。

    一个例子可以说明一切

     1  #include "stdafx.h" 
     2  #include <iostream> 
     3   
     4  class NumUpper 
     5  { 
     6  public: 
     7    
     8    //前缀,返回引用 
     9     NumUpper& operator++() 
    10     { 
    11       std::cout << "++ prefix
    "; 
    12    
    13       *this += 1; //operator+= 
    14       return *this; 
    15     } 
    16    
    17     //后缀 返回const对象,int参数 
    18     const NumUpper operator++(int)  
    19     { 
    20       std::cout << "postfix ++ 
    "; 
    21    
    22       NumUpper preNum = *this; 
    23       ++(*this); 
    24       return preNum; 
    25     } 
    26    
    27      NumUpper& operator+=(int num) 
    28      { 
    29        mNum += num; 
    30        return *this; 
    31      } 
    32    
    33   private: 
    34     int mNum; 
    35   }; 
    36    
    37   //main 
    38   int main(int argc, char* argv[]) 
    39   { 
    40    
    41     NumUpper upper; 
    42    
    43     //前置 
    44     std::cout << "-----------------------
    "; 
    45     ++upper; 
    46    
    47     //后置 
    48     std::cout << "-----------------------
    "; 
    49     upper++; 
    50    
    51     //前置 
    52     std::cout << "-----------------------
    "; 
    53     upper.operator++(); 
    54      
    55     //后置 
    56     std::cout << "-----------------------
    "; 
    57     upper.operator++(0); 
    58    
    59     std::cout << "-----------------------
    "; 
    60     system("pause"); 
    61     return 0; 
    62   } 
    63   

    //output:

    ----------------------- 
    ++ prefix 
    ----------------------- 
    postfix ++ 
    ++ prefix 
    ----------------------- 
    ++ prefix 
    ----------------------- 
    postfix ++ 
    ++ prefix 
    ----------------------- 
    请按任意键继续. . .

    从上面的例子可以看到:

    前缀形式返回一个引用

    后缀形式返回一个const类型对象

    三、其它联想

    1.const的使用

    比如不能用 upper++++这样,因为返回的是const,正好这个const就是为了防止这么连加用的。

    2.对自减也是一样

    3.还是效率问题

    (1)如编程规范所说,不要进行不成熟的劣化:

    <1>在使用前置++操作很合适的场合,却偏偏使用了后置++

    <2>可以传引用的时候,去偏偏用了传值

    <3> 构造函数中可以使用初始化列表,却偏偏使用赋值

    (2)大气使用,该用后置的时候还是要用后置,正确远比高效重要

    四、引用参考:

    《More Effective C++》

    C++ Standard Library

    第二篇:转自 http://www.cnblogs.com/maxwellp/archive/2012/02/11/2346844.html

    《C++ Primer》确实给我带来了很多惊喜。

    作为一本专业的具有较高门槛的"入门书",它有很多地方实在是国内的书不可及的,这不仅在于内容上的严谨,更表现在优秀的习题所带给学习者的启迪。

    习题5.16

    你认为为什么C++不叫做++C?

    看到这个习题,顿感眼前一亮(不禁想起某些国内书籍的题目,真是平淡如水),这对于理解前自增操作与后自增操作而言着实是个好的题目。

    想弄明白这个问题,就需要先理解一些基础的概念。什么是自增操作呢?

    ++操作符,即自增操作符。自增操作符有两种形式:前置操作和后置操作。前自增操作生成左值,在给操作数加1后返回改变后的操作数值。后自增操作生成右值,给操作数加1但返回未改变的操作数原值。

    *事实上,因为C++具有操作符重载的功能,自增操作不仅仅可以表示加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

    附左值与右值的概念:

    左值:可以出现在赋值操作左边的值。非const左值可读可写。

    右值:可用于赋值操作的右边但不能用于左边的值。右值只能读不能写。

    左值可以出现在赋值操作右端,但右值不可以出现在赋值操作左端,将后自增操作置于赋值操作左端将会出现编译错误。

    另外需要注意:

    由于后置操作符要返回未加1前的值作为操作的结果,所以必须要保存操作数原来的值(即上一篇说的临时对象),对于比较复杂的类型,这种额外工作可能会花费更大的代价。

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

    最后,让我们用全新的角度去审视C++的命名原因

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

    如果以后有人问你这个问题,你会回答了吗?囧。

  • 相关阅读:
    第七周作业
    第六周作业
    第四周作业
    第三周作业
    第二周作业
    第一周作业
    第0次作业
    第四次作业
    第三次作业
    第二次作业
  • 原文地址:https://www.cnblogs.com/kira2will/p/3550013.html
Copyright © 2011-2022 走看看