C语言举例讲解i++与++i之间的区别
目录
- 1.++i和i++的区别
- 2.++i与i++哪个效率更高
- 3.总结
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++的习惯哦!
到此这篇关于C语言举例讲解i++与++i之间的区别的文章就介绍到这了,更多相关C语言 i++与++i内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!