【C++】前置操作符(++i)和後置操作符(i++)
阿新 • • 發佈:2018-12-12
一、自增和自減的基本使用方法
自增的兩種形式:
i++ | i 的值作為返回值,i 自增 1; |
++i | i 自增 1,i 的值作為返回值。 |
Example:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int i = 0;
i++;
++i;
getchar();
return 0;
}
檢視上面程式碼段的彙編程式碼:
i++; 00931765 mov eax,dword ptr [i] 00931768 add eax,1 0093176B mov dword ptr [i],eax ++i; 0093176E mov eax,dword ptr [i] 00931771 add eax,1 00931774 mov dword ptr [i],eax
可見,兩個操作方式的彙編彙編程式碼完全相同,只是存放的暫存器不同。主要原因是編譯器對其做了優化。
1、現代編譯器產品會對程式碼進行優化; |
2、優化使得最終的二進位制程式更加高效; |
3、優化後的二進位制程式丟失了C/C++的原生語義; |
4、不可能從編譯後的二進位制程式還原C/C++程式。 |
二、自增自減面試題
接下來看一道經典的面試題:
Question :考慮下面的兩個程式碼片段來列印vector。其中一個與另一個有什麼優勢嗎?
選項1:
vector vec; /* ... .. ... */ for (auto itr = vec.begin(); itr != vec.end(); itr++) { itr->print(); }
選項2:
vector vec;
/* ... .. ... */
for (auto itr = vec.begin(); itr != vec.end(); ++itr) {
itr->print();
}
Explanation :
雖然兩種選項都可以完全相同,但從效能的角度來看,第二種選擇更好。 這是因為後增操作符(即itr ++)比前增操作符(即++ itr)更昂貴。 後增操作符的底層實現在遞增之前建立元素的拷貝,然後返回拷貝。 也就是說,許多編譯器會自動優化第一個選項,將其轉換為第二個選項。
三、 ++ 操作符過載
1.全域性函式和成員函式均可進行過載 |
2.過載前置 ++ 操作符不需要額外的引數 |
3.過載後置 ++ 操作符需要一個int型別的佔位引數 |
Example:根據C++中的原生語義過載 ++ 操作符
#include <iostream>
#include <string>
using namespace std;
class Test
{
int mValue;
public:
Test(int i)
{
mValue = i;
}
int value()
{
return mValue;
}
Test& operator ++ ()
{
++mValue;
return *this; //返回引用
}
Test operator ++ (int) //後置++
{
Test ret(mValue); //將當前的值先儲存下來
mValue++; //將當前物件自增1
return ret; //返回當前物件
}
};
int main()
{
Test t(0);
t++; //需要呼叫建構函式和解構函式
++t; //效率更高,沒有生成額外的物件
//意味著不需要呼叫棧上的記憶體,
//不需要呼叫建構函式、解構函式
return 0;
}
四、總結:++ i 和 i ++ 真正的區別...
對於基礎型別的變數
1.前置 ++ 的效率與後置 ++ 的效率基本相同 |
2.根據專案組編碼規範進行選擇 |
對於類型別的物件
1.前置 ++ 的效率高於後置 ++ |
2.儘量使用前置 ++ 操作符提高程式效率 |
Reference: