一、聯繫與區別-表格總結
++i | i++ | ||
聯繫 | 實現自加操作 | ||
區別 | 返回值 | i+1 | i |
速度 | 較快 | 較慢 | |
作爲左值 | 可以 | 不可以 |
1.1解釋:
(1) 返回值不一樣:
前置返回的i+1;
int a = 0;
int b = ++a; // 結果是 b=1, a=1
後置返回的i;
int a = 0;
int b = a++; // 結果是 a=1, b=0
所以:
i++ :先引用後增加,先在i所在的表達式中使用i的當前值,後讓i加1
++i :先增加後引用,讓i先加1,然後在i所在的表達式中使用i的新值
(2) 執行速度不一樣:
++i 速度更快的解釋:因爲i++需要對錶達式的值進行拷貝,需要維護一個臨時變量。
使用建議:
對於迭代器和其他模板對象使用前綴形式(++i)的自增、自減運算符。-------------------谷歌編程規範
二、源碼
i++實現的代碼爲:
int operator++(int)
{
int temp = *this; //先引用
++*this; //後增加
return temp;
}//返回一個int型的對象本身
++i的實現代碼爲:
int& operator++()
{
*this += 1; //先增加
return *this; //後引用
}//返回一個int型的對象引用
則:i++返回的是i的值,而++i返回的是i+1的值。
也就是++i是一個確定的值,是一個可修改的左值,如下使用:
cout << ++(++(++i)) << endl;
cout << ++ ++i << endl;
可以不停的嵌套++i。
三、題目:
這裏有很多的經典筆試題,一起來觀摩下:
#include <iostream>
int main()
{
int i = 1;
printf("%d,%d\n", ++i, ++i); //3,3
printf("%d,%d\n", ++i, i++); //5,3
printf("%d,%d\n", i++, i++); //6,5
printf("%d,%d\n", i++, ++i); //8,9//特別注意!!
system("pause");
return 0;
}
//注意:這裏面改變的是this 還是 i 還是 tmp
3.1 題目解析:
首先是函數的入棧順序從右向左入棧的,計算順序也是從右往左計算的,不過都是計算完以後在進行的壓棧操作:
對於第6行代碼,首先執行++i,返回值是i,這時i的值是2,再次執行++i,返回值是i,得到i=3,將i壓入棧中,此時i爲3,也就是壓入3,3;
對於第7行代碼,首先執行i++,返回值是原來的i,也就是3,再執行++i,返回值是i,依次將3,5壓入棧中得到輸出結果
對於第8行代碼,首先執行i++,返回值是5,再執行i++返回值是6,依次將5,6壓入棧中得到輸出結果
對於第9行代碼,首先執行++i,返回i,此時i爲8,再執行i++,返回值是8,此時i爲9,依次將i,8也就是9,8壓入棧中,得到輸出結果。
上面的分析也是基於vs搞的,不過準確來說函數多個參數的計算順序是未定義的(the order of evaluation of function arguments are undefined)。筆試題目的運行結果隨不同的編譯器而異。
參考:http://www.stroustrup.com/bs_faq2.html#evaluation-order
參考資料:
在程序開發中,++i 與 i++的區別在哪裏?:https://www.zhihu.com/question/19811087
C/C++語言中 i++ 和 ++i 有什麼區別?:http://www.slyar.com/blog/c-zizeng.html