網站首頁 編程語言 正文
1.++i和i++的區別
眾所周知的(也是學校教的),就是先自增再賦值還是先賦值再自增的區別。
#include<iostream>
using namespace std;
int main()
{
int a = 0;
int b = 0;
int c = ++a;
int d = b++;
cout << "c = " << c << endl;
cout << "d = " << d << endl;
return 0;
}
- a先自增再賦值給c,所以輸出c為1。
- b先賦值給d再自增,所以輸出d為0。
從這個方面來看,++i與i++的區別(尤其是性能方面)沒有什么差別,很多同學也并沒有思考過這個問題。
2.++i與i++哪個效率更高
下面是兩段源碼及其通過vs反匯編得到的匯編代碼:
使用++i
#include<iostream>
using namespace std;
int main()
{
for (int i = 0; i < 100; ++i)
{
cout << "hello world" << endl;
}
return 0;
}
#include<iostream>
using namespace std;
int main()
{
00552540 ?push ? ? ? ?ebp
00552541 ?mov ? ? ? ? ebp,esp
00552543 ?sub ? ? ? ? esp,0CCh
00552549 ?push ? ? ? ?ebx
0055254A ?push ? ? ? ?esi
0055254B ?push ? ? ? ?edi
0055254C ?lea ? ? ? ? edi,[ebp-0Ch]
0055254F ?mov ? ? ? ? ecx,3
00552554 ?mov ? ? ? ? eax,0CCCCCCCCh
00552559 ?rep stos ? ?dword ptr es:[edi]
0055255B ?mov ? ? ? ? ecx,offset _57B8321F_源@cpp (055F029h)
00552560 ?call ? ? ? ?@__CheckForDebuggerJustMyCode@4 (055137Fh)
?? ?for (int i = 0; i < 100; ++i)
00552565 ?mov ? ? ? ? dword ptr [ebp-8],0
0055256C ?jmp ? ? ? ? __$EncStackInitStart+2Bh (0552577h)
0055256E ?mov ? ? ? ? eax,dword ptr [ebp-8]
00552571 ?add ? ? ? ? eax,1
00552574 ?mov ? ? ? ? dword ptr [ebp-8],eax
00552577 ?cmp ? ? ? ? dword ptr [ebp-8],64h
0055257B ?jge ? ? ? ? __$EncStackInitStart+5Ch (05525A8h)
?? ?{
?? ??? ?cout << "hello world" << endl;
0055257D ?mov ? ? ? ? esi,esp
0055257F ?push ? ? ? ?offset std::endl<char,std::char_traits<char> > (055103Ch)
00552584 ?push ? ? ? ?offset string "hello world" (0559B30h)
00552589 ?mov ? ? ? ? eax,dword ptr [__imp_std::cout (055D0D4h)]
0055258E ?push ? ? ? ?eax
0055258F ?call ? ? ? ?std::operator<<<std::char_traits<char> > (05511A9h)
00552594 ?add ? ? ? ? esp,8
00552597 ?mov ? ? ? ? ecx,eax
00552599 ?call ? ? ? ?dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (055D0A0h)]
0055259F ?cmp ? ? ? ? esi,esp
005525A1 ?call ? ? ? ?__RTC_CheckEsp (055128Fh)
?? ?}
005525A6 ?jmp ? ? ? ? __$EncStackInitStart+22h (055256Eh)
?? ?return 0;
005525A8 ?xor ? ? ? ? eax,eax
}
使用i++
#include<iostream>
using namespace std;
int main()
{
for (int i = 0; i < 100; i++)
{
cout << "hello world" << endl;
}
return 0;
}
?#include<iostream>
using namespace std;
int main()
{
008B2540 ?push ? ? ? ?ebp
008B2541 ?mov ? ? ? ? ebp,esp
008B2543 ?sub ? ? ? ? esp,0CCh
008B2549 ?push ? ? ? ?ebx
008B254A ?push ? ? ? ?esi
008B254B ?push ? ? ? ?edi
008B254C ?lea ? ? ? ? edi,[ebp-0Ch]
008B254F ?mov ? ? ? ? ecx,3
008B2554 ?mov ? ? ? ? eax,0CCCCCCCCh
008B2559 ?rep stos ? ?dword ptr es:[edi]
008B255B ?mov ? ? ? ? ecx,offset _57B8321F_源@cpp (08BF029h)
008B2560 ?call ? ? ? ?@__CheckForDebuggerJustMyCode@4 (08B137Fh)
?? ?for (int i = 0; i < 100; i++)
008B2565 ?mov ? ? ? ? dword ptr [ebp-8],0
008B256C ?jmp ? ? ? ? __$EncStackInitStart+2Bh (08B2577h)
008B256E ?mov ? ? ? ? eax,dword ptr [ebp-8]
008B2571 ?add ? ? ? ? eax,1
008B2574 ?mov ? ? ? ? dword ptr [ebp-8],eax
008B2577 ?cmp ? ? ? ? dword ptr [ebp-8],64h
008B257B ?jge ? ? ? ? __$EncStackInitStart+5Ch (08B25A8h)
?? ?{
?? ??? ?cout << "hello world" << endl;
008B257D ?mov ? ? ? ? esi,esp
008B257F ?push ? ? ? ?offset std::endl<char,std::char_traits<char> > (08B103Ch)
008B2584 ?push ? ? ? ?offset string "hello world" (08B9B30h)
008B2589 ?mov ? ? ? ? eax,dword ptr [__imp_std::cout (08BD0D4h)]
008B258E ?push ? ? ? ?eax
008B258F ?call ? ? ? ?std::operator<<<std::char_traits<char> > (08B11A9h)
008B2594 ?add ? ? ? ? esp,8
008B2597 ?mov ? ? ? ? ecx,eax
008B2599 ?call ? ? ? ?dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (08BD0A0h)]
008B259F ?cmp ? ? ? ? esi,esp
008B25A1 ?call ? ? ? ?__RTC_CheckEsp (08B128Fh)
?? ?}
008B25A6 ?jmp ? ? ? ? __$EncStackInitStart+22h (08B256Eh)
?? ?return 0;
008B25A8 ?xor ? ? ? ? eax,eax
}
哈哈哈哈哈,有的同學已經發現了,好像并沒有什么區別。
之前的說法是++i比i++的效率更高,但隨著編譯器的不斷優化,兩者簡單應用時并沒有什么區別。
但是,真是如此嗎?
i++使用時,要先用將自身數據拷貝到臨時變量中,再自增,最后傳輸臨時變量。
而++i并不需要這般麻煩,直接自增再傳輸即可。一些追求壓縮空間和時間的嵌入式工程師往往喜歡使用++i。
下面通過運算符重載自實現++i和i++來解釋:
#include<iostream>
using namespace std;
class MyInt
{
friend ostream& operator<<(ostream& cout, MyInt& a);//友元
public:
MyInt();
MyInt& operator++();//前置++
MyInt& operator++(int);//使用占位參數區別前后置++,使之可以發生函數重載
private:
int m_num;
};
MyInt::MyInt()
{
this->m_num = 0;
}
MyInt& MyInt::operator++()
{
this->m_num++;
return *this;
}
MyInt& MyInt::operator++(int)
{
static MyInt temp = *this;
this->m_num++;
return temp;
}
ostream& operator<<(ostream& cout, MyInt& a)
{
cout << a.m_num;
return cout;
}
通過上面的代碼顯而易見其區別,且后置++難以實現鏈式編程。
3.總結
普通簡單使用的情況下,兩者并沒有什么區別。
但在某些機器情況下或在類中使用時,++i的效率更高。
初學小白可以養成使用++i而非i++的習慣哦!
原文鏈接:https://blog.csdn.net/GG_Bruse/article/details/124104470
相關推薦
- 2023-01-05 Kotlin?協程與掛起函數及suspend關鍵字深入理解_Android
- 2022-10-26 Jenkins+Docker?一鍵自動化部署?SpringBoot?項目的詳細步驟_docker
- 2022-05-25 kubectl操作命令及使用說明總結_云和虛擬化
- 2022-07-14 Android自定義相機、預覽區域裁剪_Android
- 2021-12-24 基于PostgreSQL/openGauss?的分布式數據庫解決方案_PostgreSQL
- 2022-07-26 讓一個有寬高的盒子垂直水平居中
- 2021-12-03 Centos8環境下修改ssh端口號方法_Linux
- 2023-02-18 Framework中實現OC和Swift的混編方案_IOS
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支