C語(yǔ)言舉例講解i++與++i之間的區(qū)別
1.++i和i++的區(qū)別
眾所周知的(也是學(xué)校教的),就是先自增再賦值還是先賦值再自增的區(qū)別。
#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。
從這個(gè)方面來(lái)看,++i與i++的區(qū)別(尤其是性能方面)沒(méi)有什么差別,很多同學(xué)也并沒(méi)有思考過(guò)這個(gè)問(wèn)題。
2.++i與i++哪個(gè)效率更高
下面是兩段源碼及其通過(guò)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
}
哈哈哈哈哈,有的同學(xué)已經(jīng)發(fā)現(xiàn)了,好像并沒(méi)有什么區(qū)別。
之前的說(shuō)法是++i比i++的效率更高,但隨著編譯器的不斷優(yōu)化,兩者簡(jiǎn)單應(yīng)用時(shí)并沒(méi)有什么區(qū)別。
但是,真是如此嗎?
i++使用時(shí),要先用將自身數(shù)據(jù)拷貝到臨時(shí)變量中,再自增,最后傳輸臨時(shí)變量。
而++i并不需要這般麻煩,直接自增再傳輸即可。一些追求壓縮空間和時(shí)間的嵌入式工程師往往喜歡使用++i。
下面通過(guò)運(yùn)算符重載自實(shí)現(xiàn)++i和i++來(lái)解釋:
#include<iostream> using namespace std; class MyInt { friend ostream& operator<<(ostream& cout, MyInt& a);//友元 public: MyInt(); MyInt& operator++();//前置++ MyInt& operator++(int);//使用占位參數(shù)區(qū)別前后置++,使之可以發(fā)生函數(shù)重載 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; }
通過(guò)上面的代碼顯而易見(jiàn)其區(qū)別,且后置++難以實(shí)現(xiàn)鏈?zhǔn)骄幊獭?/p>
3.總結(jié)
普通簡(jiǎn)單使用的情況下,兩者并沒(méi)有什么區(qū)別。
但在某些機(jī)器情況下或在類中使用時(shí),++i的效率更高。
初學(xué)小白可以養(yǎng)成使用++i而非i++的習(xí)慣哦!
到此這篇關(guān)于C語(yǔ)言舉例講解i++與++i之間的區(qū)別的文章就介紹到這了,更多相關(guān)C語(yǔ)言 i++與++i內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)關(guān)系與關(guān)系矩陣的代碼詳解
這篇文章主要介紹了C++實(shí)現(xiàn)關(guān)系與關(guān)系矩陣,功能實(shí)現(xiàn)包括關(guān)系的矩陣表示,關(guān)系的性質(zhì)判斷及關(guān)系的合成,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04VS中的scanf_s函數(shù)和scanf用法及說(shuō)明
這篇文章主要介紹了VS中的scanf_s函數(shù)和scanf用法及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)的時(shí)間復(fù)雜度和空間復(fù)雜度
算法在編寫(xiě)成可執(zhí)行程序后,運(yùn)行時(shí)需要耗費(fèi)時(shí)間資源和空間(內(nèi)存)資源 。因此衡量一個(gè)算法的好壞,一般是從時(shí)間和空間兩個(gè)維度來(lái)衡量的,即時(shí)間復(fù)雜度和空間復(fù)雜度,感興趣的同學(xué)可以參考閱讀2023-04-04C++學(xué)習(xí)之算術(shù)運(yùn)算符使用詳解
運(yùn)算符是計(jì)算機(jī)語(yǔ)言提供的能對(duì)數(shù)據(jù)進(jìn)行基本運(yùn)算操作的功能體。而算術(shù)運(yùn)算符用來(lái)對(duì)數(shù)字型數(shù)據(jù)進(jìn)行數(shù)學(xué)語(yǔ)義上的加、減、乘、除。本文通過(guò)講解清楚算術(shù)運(yùn)算符,讓大家了解使用C++運(yùn)算符時(shí)應(yīng)該注意的事項(xiàng)2022-06-06利用C語(yǔ)言來(lái)求最大連續(xù)子序列乘積的方法
這篇文章主要介紹了利用C語(yǔ)言來(lái)求最大連續(xù)子序列乘積的方法,基本的思路以外文中還附有相關(guān)ACM題目,需要的朋友可以參考下2015-08-08C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的三子棋游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)三子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-09-09C++?qt實(shí)現(xiàn)打開(kāi)關(guān)閉狀態(tài)按鈕的代碼
這篇文章主要介紹了C++?qt實(shí)現(xiàn)打開(kāi)關(guān)閉狀態(tài)按鈕,用QCheckBox可以實(shí)現(xiàn),只要在選擇與未選擇的狀態(tài)設(shè)置不同的圖片即可完成,代碼簡(jiǎn)單易懂,需要的朋友可以參考下2022-03-03