昨天同学问了我一个这样的问题:
请问下面这个程序的输出是多少?
-
#include<iostream>
-
using namespace std;
-
int main()
-
{
-
int a = 2;
-
cout << (a++)*(a++) << endl;
-
cout << "a = " << a << endl;
-
return 0;
-
}
我不假思索就喊出了:
6;
4;
不知道大家一开始是怎么认为的,但是实际的结果却是:
4;
4;
可能这个题目大多人还是知道结果,然后又来了一个:
-
#include<iostream>
-
using namespace std;
-
int main()
-
{
-
volatile int a = 2;
-
cout << (a++)*(a++) << endl;
-
cout << "a = " << a << endl;
-
return 0;
-
}
结果又是多少呢?
4;
3;
下一道:
-
#include<iostream>
-
using namespace std;
-
int main()
-
{
-
int a = 2;
-
cout << (++a)*(++a) << endl;
-
cout << "a = " << a << endl;
-
return 0;
-
}
结果是:
16
4
接着又是一道:
-
#include<iostream>
-
using namespace std;
-
int main()
-
{
-
volatile int a = 2;
-
cout << (++a)*(++a) << endl;
-
cout << "a = " << a << endl;
-
return 0;
-
}
结果:
12;
4;
假如经过上面的例子你觉得你似乎好象是明白了,编译器是怎么个顺序,那么我们接着看:
-
#include<iostream>
-
using namespace std;
-
int main()
-
{
-
volatile int a = 2;
-
cout << (a++)*(++a) << endl;
-
cout << "a = " << a << endl;
-
return 0;
-
}
结果是多少呢?
6;
3
最后一道:
-
#include<iostream>
-
using namespace std;
-
int main()
-
{
-
volatile int a = 2;
-
cout << (++a)*(a++) << endl;
-
cout << "a = " << a << endl;
-
return 0;
-
}
结果:
9;
4;
我们来总结一下在g++,编译器环境下:
首先明确的一点是前置++计算之后立即更改内存中值和缓存中值,而后置++,计算完之后会将结果放入临时缓存,待表达式执行完成再写回内存!
1、如果我们在表达式中存在(i++),一律返回原来的数值,等表达式执行结束,将所有后置++的缓存结果写回!
2、假如表达式中存在多个(++i)的操作,在进行表达式计算之前将所有前置++的值计算完毕,返回给表达式进行计算。
3、假如表达式中存在i++和++i的时候,会优先进行++i的操作并且更改i的值,等到表示执行完毕后,再进行后置++操作,再次更改i的值。
4、但是如果加上volatile关键之后,无论什么情况,表达式都会按照从左向右的顺序进行计算,如果碰到前置++就去内存中将值读取修改后写入缓存和内存,如果碰到后置++去内存读取数值返回,将修改后的值存入缓存。待表达式执行完成后,将缓存中的数值写入内存。
总结下来大家会发现,对++这个操作还是很绕,所以很容易产生坑,所以java为了填坑就做了明确的规定,无论什么情况下表达式都是从左向右进行计算,前置++返回修改后的值,后置++返回修改前的值,待表达式执行完成将所有的++的结果一起清算写入内存。
阅读(1641) | 评论(1) | 转发(1) |