C++-有关++的一些问题
请问,(a++)++,(++a)++,++(a++),++(++a)能够编译通过么?如果可以,那么运行之后a的值是多少?如果不能,为什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
请问,(a++)++,(++a)++,++(a++),++(++a)能够编译通过么?如果可以,那么运行之后a的值是多少?如果不能,为什么?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(9)
用c或c++都不行.++X或者X++其中X必须是变量,而不能是表达式或是常量,只能是变量(如有不妥之处,只属个人理解,敬请高手指教)
不能通过编译,因为++操作需要一个左值,a++后返回的是一个右值,所以(a++)++不能通过编译。其它同理。
不能,第一句就报错啦!
Invalid argument to operation ++/--
本来没那么复杂的就没有必要写得那么复杂,你可以这样写:
b = a++;
c = b++;
....
a++或者++a,返回的值是一个右值,而不是左值(一个地址),再次进行++操作的时候就会报错。
在进行运算的时候,只有左值可以储存结果,而右值只能做运算过程的一部分。
括号运算符返回的结果是括号里的置,假设a=0,(++a)++计算分两步,先计算(++a),结果为1,然后就是1++,显然编译出错。其他的依此类推。
简单说下我的想法:
因为一元运算符++操作需要一个左值,a++后返回的是一个右值,语法检查是很难通过的。
完全没有必要这么写,而且这么写很多时候要看编译器是怎么处理的,很有可能不同的编译器给出不同的结果,这个是正常的,特别是C语言现在就有三个标准,从Old style到新的C99等标准。
其他语言(非C语言)视乎对这写写法解析也不太一样,我感觉Lua是最特殊的。
要试这种类似的东西,楼主可以自己编个小程序去试一下,没有必要在这里问。但是,既然问了我也就告诉你了。这些个运行之后的结果都是a+2
刚刚我试了一下,好像编译通过不了。。。
这个其实是和编译器有关的。
那么以VS2008为例来说吧~
上述代码的编译结果:
1>------ 已启动生成: 项目: test30, 配置: Debug Win32 ------
1>正在编译...
1>main.cpp
1>g:workspaceexercisecppprimertest30test30main.cpp(8) : error C2105: “++”需要左值
1>g:workspaceexercisecppprimertest30test30main.cpp(12) : error C2105: “++”需要左值
即(a++)++;和++(a++);会编译出错,其他的通过编译。原因如下:
后置++返回右值,而前置++返回左值。
其实,看下前置和后置++的实现就知道的很清楚了,这是从《C++ Primer(第三版)》上摘下来的一段代码,是实现对复数对象的操作符重载:
前置:
inline complex<double>&
operator++(complex<double> &cval)
{
return cval += complex<double>(1);
}
后置:
inline complex<double>
operator++(complex<double> &cval,int)
{
complex<doble> oldval = cval;
cval += complex<double>(1);
return oldval;
}
你会发现,前置++是返回的左值,而后置++返回的是一个局部变量,是右值。
再举一个例子,假设有一个类Age,描述年龄。该类重载了前置++和后置++两个操作符,以实现对年龄的自增。
1. class Age
2. {
3. public:
4.
5. Age& operator++() //前置++
6. {
7. ++i;
8. return *this;
9. }
10.
11. const Age operator++(int) //后置++
12. {
13. Age tmp = *this;
14. ++(*this); //利用前置++
15. return tmp; //注意:返回的是临时对象
16. }
17.
18. Age& operator=(int i) //赋值操作
19. {
20. this->i = i;
21. return *this;
22. }
23.
24. private:
25. int i;
26. };
从上述代码,我们可以看出前置++和后置++,有4点不同:
1. 返回类型不同
2. 形参不同
3. 代码不同
4. 效率不同
返回值类型的区别前置++的返回类型是Age&,后置++的返回类型const Age。这意味着,前置++返回的是左值,后置++返回的是右值。
左值和右值,决定了前置++和后置++的用法。
1. int main()
2. {
3. Age a;
4.
5. (a++)++; //编译错误
6. ++(a++); //编译错误
7. a++ = 1; //编译错误
8. (++a)++; //OK
9. ++(++a); //OK
10. ++a = 1; //OK
11. }
a++的类型是const Age,自然不能对它进行前置++、后置++、赋值等操作。
++a的类型是Age&,当然能对它进行前置++、后置++、赋值等操作。
看一下这一篇日志,<C/C++> 左值和右值, L-value和R-value
可能会有所体会。