C语言举例讲解i++与++i之间的区别

 更新时间:2022年05月11日 14:08:37   作者:GG_Bond18  
这篇文章主要介绍了C语言中i++和++i的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入了解C语言的动态内存管理

    深入了解C语言的动态内存管理

    所谓动态和静态就是指内存的分配方式。动态内存是指在堆上分配的内存,而静态内存是指在栈上分配的内存,本文将用5600字带你深入了解动态内存管理,感兴趣的可以学习一下
    2022-07-07
  • C语言详尽图解函数栈帧的创建和销毁实现

    C语言详尽图解函数栈帧的创建和销毁实现

    我们知道c语言中函数都是被调用的,main函数里面能调用其他函数,其实main函数也是被别的函数调用的,下面通过本文给大家分享c语言函数栈帧的创建和销毁过程,一起看看吧
    2022-05-05
  • 哈夫曼的c语言实现代码

    哈夫曼的c语言实现代码

    着先通过 HuffmanTree() 函数构造哈夫曼树,然后在主函数 main()中自底向上开始(也就是从数组序号为零的结点开始)向上层层判断,若在父结点左侧,则置码为 0,若在右侧,则置码为 1。最后输出生成的编码
    2013-07-07
  • Qt扫盲篇之QRegularExpression正则匹配总结

    Qt扫盲篇之QRegularExpression正则匹配总结

    QRegularExpression是Qt5.0引进的,修复了很多bug,提高了效率,使用时建议使用QRegularExpression,下面这篇文章主要给大家介绍了关于Qt扫盲篇之QRegularExpression正则匹配的相关资料,需要的朋友可以参考下
    2023-03-03
  • Opencv实现视频播放与进度控制

    Opencv实现视频播放与进度控制

    这篇文章主要为大家详细介绍了Opencv实现视频播放与进度控制,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • visual studio 2022中的scanf问题解决

    visual studio 2022中的scanf问题解决

    昨天在使用Visual Studio 2022编写C语言程序时遇到了scanf问题,对于vs的编译器来说scanf是不安全的,编译器通过不了scanf,本文就来介绍一下解决方法,感兴趣的可以了解一下
    2023-12-12
  • c++版线程池和任务池示例

    c++版线程池和任务池示例

    这篇文章主要介绍了c++版线程池和任务池,实现任务执行完毕线程退出.在linux下压力测试通过
    2014-03-03
  • 聊聊C++中右值引用和移动构造函数的使用

    聊聊C++中右值引用和移动构造函数的使用

    这篇文章主要是来和大家一起聊聊C++中右值引用和移动构造函数的使用,文中通过示例进行了详细讲解,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-07-07
  • C语言 结构体和指针详解及简单示例

    C语言 结构体和指针详解及简单示例

    本文主要介绍C语言 结构体和指针,这里整理了相关资料,并附示例代码和实现结果,以便大家学习参考,希望能帮助学习C语言的朋友
    2016-08-08
  • c++11中regex正则表达式示例简述

    c++11中regex正则表达式示例简述

    这篇文章主要给大家介绍了关于c++11中regex正则表达式的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用c++11具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-11-11

最新评论