Chinaunix首页 | 论坛 | 博客
  • 博客访问: 624773
  • 博文数量: 79
  • 博客积分: 848
  • 博客等级: 军士长
  • 技术积分: 1800
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-26 19:30
文章分类

全部博文(79)

文章存档

2015年(4)

2013年(39)

2012年(36)

分类: C/C++

2013-03-22 11:31:58

昨天同学问了我一个这样的问题:
请问下面这个程序的输出是多少?

点击(此处)折叠或打开

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5.     int a = 2;
  6.     cout << (a++)*(a++) << endl;
  7.     cout << "a = " << a << endl;
  8.     return 0;
  9. }

我不假思索就喊出了:
6;
4;
不知道大家一开始是怎么认为的,但是实际的结果却是:
4;
4;
可能这个题目大多人还是知道结果,然后又来了一个:

点击(此处)折叠或打开

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5.     volatile int a = 2;
  6.     cout << (a++)*(a++) << endl;
  7.     cout << "a = " << a << endl;
  8.     return 0;
  9. }
结果又是多少呢?
4;
3;
下一道:

点击(此处)折叠或打开

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5.     int a = 2;
  6.     cout << (++a)*(++a) << endl;
  7.     cout << "a = " << a << endl;
  8.     return 0;
  9. }
结果是:
16
4
接着又是一道:

点击(此处)折叠或打开

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5.     volatile int a = 2;
  6.     cout << (++a)*(++a) << endl;
  7.     cout << "a = " << a << endl;
  8.     return 0;
  9. }
结果:
12;
4;
假如经过上面的例子你觉得你似乎好象是明白了,编译器是怎么个顺序,那么我们接着看:

点击(此处)折叠或打开

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5.     volatile int a = 2;
  6.     cout << (a++)*(++a) << endl;
  7.     cout << "a = " << a << endl;
  8.     return 0;
  9. }
结果是多少呢?
6;
3
最后一道:

点击(此处)折叠或打开

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5.     volatile int a = 2;
  6.     cout << (++a)*(a++) << endl;
  7.     cout << "a = " << a << endl;
  8.     return 0;
  9. }
结果:
9;
4;
我们来总结一下在g++,编译器环境下:
首先明确的一点是前置++计算之后立即更改内存中值和缓存中值,而后置++,计算完之后会将结果放入临时缓存,待表达式执行完成再写回内存!
1、如果我们在表达式中存在(i++),一律返回原来的数值,等表达式执行结束,将所有后置++的缓存结果写回!
2、假如表达式中存在多个(++i)的操作,在进行表达式计算之前将所有前置++的值计算完毕,返回给表达式进行计算。
3、假如表达式中存在i++和++i的时候,会优先进行++i的操作并且更改i的值,等到表示执行完毕后,再进行后置++操作,再次更改i的值。
4、但是如果加上volatile关键之后,无论什么情况,表达式都会按照从左向右的顺序进行计算,如果碰到前置++就去内存中将值读取修改后写入缓存和内存,如果碰到后置++去内存读取数值返回,将修改后的值存入缓存。待表达式执行完成后,将缓存中的数值写入内存。

总结下来大家会发现,对++这个操作还是很绕,所以很容易产生坑,所以java为了填坑就做了明确的规定,无论什么情况下表达式都是从左向右进行计算,前置++返回修改后的值,后置++返回修改前的值,待表达式执行完成将所有的++的结果一起清算写入内存。






阅读(1647) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~

Bean_lee2013-03-23 22:38:51

如果有人拿这种程序问我,我会直接回答,有多远给哥滚多远。
所有需要让我停下来考虑运算符优先级的代码,我都说 WTF。