一文带你彻底搞懂i++和++i的区别,谁的效率更高?

作者简介:Codebowl靓仔,学妹的工具人,C++开发误入数据开发,梦想30岁退休的靓仔就是我啦。

i++和++i对于初学者来说,一直是一个特别容易搞混的内容,相信很多人现在也没有完全搞清(作者初学的时候就一直稀里糊涂的,老师在讲这个的时候也一笔带过了)。
不过今天不用怕,看完这篇文章,相信你一定能搞清楚这俩个的区别!

基本概念

两者的作用都是自增加1。
单独拿出来说的话,++i和i++,效果都是一样的,就是i=i+1。

int main()
{
	int i = 0;
	i++;
}
int main()
{
	int i = 0;
	++i;
}

最后的结果都是1。
++i和i++运行结果

那么它们的区别又体现在什么地方呢?
请继续往下看!

++i和i++的区别

单独使用的时候是没有区别的,但是如果当成运算符,就会有区别了!
如图所示,我们用a=i++和a=++i举例说明

1.先说a=i++,这个运算的意思是先把i的值赋予a,然后在执行i=i+1;

  • 当i初始等于3时,执行a=i++,最终结果a=3,i=4.

2.而a=++i,这个的意思是先执行i=i+1,然后在把i的值赋予a;

  • 当i初始等于3时,执行a=++i,最终结果a=4,i=4.

在这里插入图片描述
所以说两者参与运算时的区别就是:

  1. a=i++ , a 返回原来的值a=i,i=i+1;
    a=++i , a 返回加1后的值,a=i+1,i=i+1。
    也就是i++是先赋值,然后再自增;++i是先自增,后赋值。
  2. 第二个区别就是: i++ 不能作为左值,而++i可以。

i++和++i的原理

实现原理我们要分俩部分看,因为单独使用和参与运算时是不一样的。

单独使用时

通过下图汇编代码所示,单独使用时,都是先进性加法,在进行赋值,所以体现出来的结果是一样的。
在这里插入图片描述

参与运算时

我们通过汇编代码,就可以很清楚地看到两者的不同了。
a=i++,先将i赋值给了a,然后才进行了+1操作,把加1结果赋值给了i。
b=++i,先进行加1操作,然后将加1结果先赋值给i,在赋值给了b。
在这里插入图片描述
其实,看汇编代码是学习C++的一个很好的方法,当我们对于某些实现原理存在疑惑的时候,就可以通过看汇编代码来学习!

i++和++i那个效率更高?

我们通过上面的两张图,单独使用的时候,两者没有区别,参与运算时,也不过是语句的执行顺序换了,但是执行的步骤是一样的,效率都是一样的啊,没有什么不同啊?
在这里插入图片描述
在这里插入图片描述
有这个疑问的小伙伴已经发现了在简单使用的时候,确实俩者的效率是没有什么不同的!
(之前存在的说法是++i比i++的效率高,但是当编译器优化之后,两者简单应用时的效率确实是没有什么不同的)

但是,答案是两者效率在某些情况下仍有不同!
当我们考虑自定义类的时候,就不一样了。
i++是先用临时对象保存原来的对象,然后对原对象自增,再返回临时对象,不能作为左值;++i是直接对于原对象进行自增,然后返回原对象的引用,可以作为左值。
由于要生成临时对象,i++需要调用两次拷贝构造函数与析构函数(将原对象赋给临时对象一次,临时对象以值传递方式返回一次);
++i由于不用生成临时变量,且以引用方式返回,故没有构造与析构的开销,效率更高。
所以在使用类等自定义类型的时候,应尽量使用++i。

实验证明:

#include<iostream>
using namespace std;

class increment {
	int x_;
	int y_;
public:
	increment(int x = 0, int y = 0);
	increment(const increment&);
	~increment();
	increment& operator++();//前置
	const increment operator++(int);//后置
	increment operator+(const increment&);
	increment& operator+=(const increment&);
	void Displayincrement();
};

increment& increment::operator+=(const increment& _right)
{
	this->x_ += _right.x_;
	this->y_ += _right.y_;
	return *this;
}

increment increment::operator+(const increment& _right)
{
	increment temp;
	temp.x_ = this->x_ + _right.x_;
	temp.y_ = this->y_ + _right.y_;
	return temp;
}


increment& increment::operator++()
{
	++x_;
	++y_;
	return *this;
}

const increment increment::operator++(int)
{
	increment temp(*this);
	this->x_++;
	this->y_++;
	return temp;
}

increment::increment(int x, int y)
{
	x_ = x;
	y_ = y;
	cout << "this is constructor" << endl;
}

increment::increment(const increment& b)
{
	this->x_ = b.x_;
	this->y_ = b.y_;
	cout << "this is copy constructor" << endl;
}

increment::~increment()
{
	cout << "this is destructor" << endl;
}

void increment::Displayincrement()
{
	cout << "x: " << this->x_ << endl;
	cout << "y: " << this->y_ << endl;
}

int main()
{
	increment i(1, 1);
	cout << endl << "this is i++: " << endl;
	i++;
	cout << endl << "this is ++i: " << endl;
	++i;
}

运行结果:
在这里插入图片描述可以看到,i++将会有两次的拷贝构造与析构的调用,效率非常低。

总结如下:

  1. 简单使用时,俩这效率没有什么区别!
  2. 对于自定义类型,在类里使用的时候,++i的效率更高!

Codebowl是个靓仔,快要毕业的大四仔。
希望可以帮助到您,喜欢的话,可以给个关注收藏或点赞哦,有不懂或发现错误的可以在评论区或私信交流哦!

  • 79
    点赞
  • 165
    收藏
    觉得还不错? 一键收藏
  • 27
    评论
Python面向对象编程(Object-Oriented Programming,简称OOP)是一种程序设计方法,它将数据和操作数据的方法组合成对象,通过定义类(class)来创建对象。下面是一些概念和原则,可以帮助你更好地理解Python面向对象编程。 1. 类和对象: - 类是一种抽象的数据类型,它定义了对象的属性和方法。 - 对象是类的实例,它具有类定义的属性和方法。 2. 属性和方法: - 属性是对象的数据,可以是整数、字符串、列表等。 - 方法是对象的行为,可以是函数或过程。 3. 封装: - 封装是将数据和对数据的操作封装在一起,以创建一个独立的实体。 - 使用类来封装数据和方法,可以隐藏实现细节,提高代码的可读性和可维护性。 4. 继承: - 继承是一种机制,允许一个类继承另一个类的属性和方法。 - 子类可以重用父类的代码,并且可以添加新的属性和方法。 5. 多态: - 多态是指同一个方法可以在不同的类中具有不同的实现方式。 - 多态可以提高代码的灵活性和可扩展性。 下面是一个简单的例子,展示了如何定义一个类、创建对象并调用对象的方法: ```python class Person: def __init__(self, name, age): self.name = name self.age = age def say_hello(self): print(f"Hello, my name is {self.name} and I'm {self.age} years old.") # 创建对象 person = Person("Alice", 25) # 调用对象的方法 person.say_hello() ``` 这个例子定义了一个名为`Person`的类,它有两个属性(`name`和`age`)和一个方法(`say_hello`)。我们通过`Person`类创建了一个名为`person`的对象,并调用了它的`say_hello`方法。 希望这个简单的例子能帮助你更好地理解Python面向对象编程。如果你有其他问题,请随时提问。
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值