递增(++)和递减(--)运算符前置版本和后置版本的区别【i++,++i的区别】

本文详细解析了C++中前置(++i)和后置(i++)递增运算符的区别。前置版本先加1再返回值,后置版本则返回加1前的值副本。通过具体代码示例,阐述了两者在内存操作和实际应用中的差异,尤其强调了后置版本的使用场景。

前置版本(++i):首先将运算对象加1,然后将改变后的对象作为求值结果;
后置版本(i++):也会将运算对象加1,但是求值结果是运算对象改变之前那个值的副本;

int i = 0,j;
j = ++i;    //j = 1,i = 1;前置版本得到递增之后的值; 即  i = i + 1, j = 1;
int i = 0,j;
j = i++;    //j = 0,i = 1;后置版本得到递增之前的值;即 j = i, i = i + 1;

两种运算符都必须作用于左值运算对象(当对象被用作左值时,用的是对象的在内存中的位置):
前置版本将对象本身作为左值返回;
后置版本将对象原始值的副本作为右值返回(当对象被用作右值,用的是对象的值(内容))。

建议:除非必须,否则不用递 增减运算符的后置版本;

使用后置版本的一个例子:

// 混用解引用和递增运算符
	vector<int> v;
	int num;
	while(cin>>num)
	{
		v.push_back(num);
	}
	auto p = v.begin();
	while(p != v.end() && *p >= 0)
	{
		cout<<*p++<<endl;    //*p++  = *(p++)
		//cout<<*p<<endl;
		//++p;
	}    //输出当前值并将p向前移动一个元素
//如果改成*++p,程序无法输出第一个元素,且如果序列中没有负值,程序将可能试图解引用一个根本不存在的元素
//我自己试的时候程序debug的时候会报错。
<think>嗯,用户想实现一个分数计算器的代码,支持加减乘除还有前置后置的++、--操作。首先,我得想清楚分数在代码里怎么表示。通常分数有分子分母,所以需要一个来封装这两个属性,比如Fraction。然后,加减乘除这些运算需要重载运算符,比如+、-、*、/,这样用户可以直接用运算符操作分数对象。接下来是前置后置的++--。根据引用[1]里的说明,递增递减运算符作用于变量、数组元素或对象属性,前置是先增减再赋值,后置是先赋值再增减。所以在Fraction里,我需要重载前置++后置++,以及前置--后置--前置的可能返回引用,后置的需要保存旧值再返回。然后,分数的运算要考虑约分,比如每次运算后要找到最大公约数来简化分数。同时,分母不能为零,所以构造函数里需要处理分母为零的情况,可能抛出异常。还有,分数的加减法需要通分,找到最小公倍数,然后调整分子相加或相减。乘法的话直接分子乘分子,分母乘分母,再约分。除法则是乘以倒数,同样注意分母不能为零。在实现运算符重载的时候,要注意C++的语法,比如重载+=的话,可以先实现+=,再基于它实现+,这样代码更简洁。同样,前置++是修改自身后返回*this,而后置++需要一个临时对象保存原来的值,再自增,返回临时对象。测试部分,用户可能需要写一些测试用例,验证各个运算符的正确性,比如分数加法是否正确,++--是否按前置后置正确执行。另外,引用[4]提到C++的Date实现了运算符重载,包括比较加减,这可以作为参考,如何结构化组织代码。比如,比较运算符重载可以用来比较两个分数的大小,而加减乘除则处理运算。还有,用户可能需要注意代码的异常处理,比如分母为零的情况,或者在除法时除数为零的情况,这时候需要抛出错误提示。最后,代码的可读性注释也很重要,确保每个方法的功能清晰,特别是运算符重载的部分,可能需要详细注释说明其行为。</think>以下是一个支持分数加减乘除及自增自减操作的C++实现方案,结合运算符重载技术实现: ```cpp #include <iostream> #include <stdexcept> using namespace std; class Fraction { private: int numerator; // 分子 int denominator; // 分母 // 最大公约数(用于约分) int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } // 约分处理 void reduce() { int common = gcd(abs(numerator), abs(denominator)); numerator /= common; denominator /= common; if(denominator < 0) { // 保证分母始终为正 numerator *= -1; denominator *= -1; } } public: Fraction(int num = 0, int den = 1) { if(den == 0) throw invalid_argument("分母不能为零"); numerator = num; denominator = den; reduce(); } // 加法运算符重载 Fraction operator+(const Fraction& other) const { return Fraction( numerator * other.denominator + other.numerator * denominator, denominator * other.denominator ); } // 减法运算符重载 Fraction operator-(const Fraction& other) const { return Fraction( numerator * other.denominator - other.numerator * denominator, denominator * other.denominator ); } // 乘法运算符重载 Fraction operator*(const Fraction& other) const { return Fraction( numerator * other.numerator, denominator * other.denominator ); } // 除法运算符重载 Fraction operator/(const Fraction& other) const { if(other.numerator == 0) throw invalid_argument("除数不能为零"); return Fraction( numerator * other.denominator, denominator * other.numerator ); } // 前置++ Fraction& operator++() { numerator += denominator; reduce(); return *this; } // 后置++ Fraction operator++(int) { Fraction temp = *this; ++(*this); return temp; } // 前置-- Fraction& operator--() { numerator -= denominator; reduce(); return *this; } // 后置-- Fraction operator--(int) { Fraction temp = *this; --(*this); return temp; } // 输出运算符重载 friend ostream& operator<<(ostream& os, const Fraction& f) { if(f.denominator == 1) os << f.numerator; else os << f.numerator << "/" << f.denominator; return os; } }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值