[c/c++] i++与++i的区别

本文详细解析了C++中前置++与后置++运算符的区别,包括它们的值、左值右值属性及效率对比。通过实例代码,展示了自定义类中这两种运算符重载的具体实现,以及它们在效率上的差异。

主要区别

  1. 值的区别
  2. 左值右值区别
  3. 效率区别

实现代码

下面以郭炜老师c++课程中的一段代码为例
类定义

class cDemo
{
private:
	int n;
public:
	cDemo(int i) : n(i) {}
	cDemo& operator++();		// 前置++
	cDemo operator++(int);		// 后置++
};

前置++

cDemo& cDemo::operator++()
{
	++n;
	return *this;
}

后置++

cDemo cDemo::operator++(int)
{
	cDemo tmp(*this);		// 赋值时调用拷贝构造函数
	n++;
	return tmp;				// 返回时调用拷贝构造函数
}

1.值的区别

由上面的例子可见:
前置++,即++i,先自增再返回,返回的值已经+1;
后置++,即i++,先保存自增前的值,然后自增,最后返回自增前的值,返回的值未+1。

2.左值右值区别

前置++,返回的是引用,属于左值,可被赋值,可取地址
后置++,返回本身类型,属于右值,不可被赋值,不可取地址
ps:下面这段代码g++可以编译通过,gcc编译报错

i++_++i.c:8:26: error: lvalue required as unary ‘&’ operand
  printf("&(++i) : %p\n", &(++i));
#include <stdio.h>

int main()
{
  int i = 7;

  printf("&i     : %p\n", &i);
  printf("&(++i) : %p\n", &(++i));
  // printf("&(i++) : %p\n", &(i++));

  ++i = 2;
  printf("++i = 2 : %d\n", i);
  // i++ = 2;

  return 0;
}

3.效率区别

对于自定义类重载的自增运算符:
前置++,直接返回引用本身,效率较高
后置++,需要调用两次拷贝构造函数,效率较低
系统内置类型自增运算符,如int
效率几乎无差别

参考阅读

[1] 自增自减运算符的重载-郭炜
[2] ++i、i++、i+=1、i=i+1的区别-白夜行的狼
[3] 在程序开发中,++i 与 i++的区别在哪里?-知乎

### C/C++ 中前置自增 `++i` 和后置自增 `i++` 的区别 在 C/C++ 编程语言中,前置自增 (`++i`) 和后置自增 (`i++`) 是两种不同的自增操作方式。 #### 运算顺序差异 前置自增 `++i` 会先对变量执行加一的操作,然后再使用更新后的值参后续计算[^2]。相反,后置自增 `i++` 则是在当前表达式中使用原始值之后再进行加一处理。 #### 性能考量 由于实现机制的不同,前置自增通常具有更高的性能表现。具体来说,当应用于复杂对象如迭代器或其他模板类实例时,采用前缀形式能够避免创建不必要的临时副本,从而提高运行效率[^1]。 #### 返回值特性 前置自增返回的是经过增量修改后的左值(lvalue),这意味着可以直接对其进行赋值等进一步操作;而后置版本则提供了一个基于原有状态复制出来的右值(rvalue),该值仅能在读取场景下发挥作用而不支持写入动作[^4]。 ```cpp // 前置自增示例 int a = 0; ++a; // 此处a变为1并立即生效 // 后置自增示例 int b = 0; b++; // 表达式的值仍为0,但在语句结束时b已变成1 ``` 为了更直观地理解两者之间的差别,下面给出一段简单的代码片段: ```cpp #include <iostream> using namespace std; class Counter { public: int value; Counter(int v): value(v) {} // Overload prefix increment operator Counter& operator++() { ++value; return *this; } // Overload postfix increment operator Counter operator++(int) { Counter temp(*this); ++(*this); return temp; } }; void print(const char* msg, const Counter& c){ cout << msg << ": " << c.value << endl; } int main(){ Counter counter(5); print("Before any operation", counter); print("Prefix Increment result", ++counter); print("After Prefix Increment", counter); Counter anotherCounter(7); print("Another Before any operation", anotherCounter); print("Postfix Increment result", anotherCounter++); print("After Postfix Increment", anotherCounter); } ``` 上述程序展示了如何通过重载运算符来区分这两种不同类型的自增行为,并且可以看到它们各自产生的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值