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语言中正切的相关函数总结

    这篇文章主要介绍了C语言中正切的相关函数总结,包括正切和反正切以及双曲线正切等的函数,需要的朋友可以参考下
    2015-08-08
  • 详解如何将Spire.PDF for C++集成到C++程序中

    详解如何将Spire.PDF for C++集成到C++程序中

    Spire.PDF for C++ 是一个专业的 PDF 库,供开发人员在任何类型的 C++ 应用程序中阅读、创建、编辑和转换 PDF 文档,本文主要介绍了两种不同的方式将 Spire.PDF for C++ 集成到您的 C++ 应用程序中,希望对大家有所帮助
    2023-11-11
  • C语言之循环语句详细介绍

    C语言之循环语句详细介绍

    大家好,本篇文章主要讲的是C语言之循环语句详细介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • 在 VSCode 中配置 C++ 开发环境的详细教程

    在 VSCode 中配置 C++ 开发环境的详细教程

    本文详细介绍了如何在Visual Studio Code(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通过这些步骤,你可以快速搭建C++开发环境,实现高效编程,感兴趣的朋友一起看看吧
    2025-01-01
  • dev-c++创建lib(静态链接库)文件的实现步骤

    dev-c++创建lib(静态链接库)文件的实现步骤

    本文主要介绍了dev-c++创建lib(静态链接库)文件的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • C++访问者模式模板函数无法重载的问题解决

    C++访问者模式模板函数无法重载的问题解决

    本文主要介绍了C++访问者模式模板函数无法重载的问题解决,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • C++基于栈的深搜算法实现马踏棋盘

    C++基于栈的深搜算法实现马踏棋盘

    这篇文章主要为大家详细介绍了C++基于栈的深搜算法实现马踏棋盘,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • 详解C语言学习记录之指针

    详解C语言学习记录之指针

    关于指针,其是C语言的重点,C语言学的好坏,其实就是指针学的好坏。其实指针并不复杂,学习指针,要正确的理解指针,本片文章能给就来学习一下
    2021-11-11
  • 浅谈C语言编程中的布尔bool数据类型

    浅谈C语言编程中的布尔bool数据类型

    这篇文章主要介绍了C语言编程中的布尔bool数据类型,bool并不是需要通过C++才能使用的,需要的朋友可以参考下
    2015-11-11
  • 详解C++编译器优化技术

    详解C++编译器优化技术

    现代编译器缺省会使用RVO(return value optimization,返回值优化)、NRVO(named return value optimization、命名返回值优化)和复制省略(Copy elision)技术,来减少拷贝次数来提升代码的运行效率。
    2021-06-06

最新评论