C++的一个疑问,关于迭代器
源程序:
#include <iostream>
#include <vector>
using std::vector;
using namespace std;
int main()
{
int word,sum;
vector<int> ivec1,ivec2;
while (cin>>word)
ivec1.push_back(word);
if (ivec1.size()%2==0)
{
for(vector<int>::iterator iter1=ivec1.begin();iter1!=ivec1.end();++iter1)
{
sum=*(iter1);
++iter1;
sum+=*(iter1);
ivec2.push_back(sum);
}
}
else
{
for(vector<int>::iterator iter1=ivec1.begin();iter1!=ivec1.end()-1;++iter1)
{
sum=*(iter1);
++iter1;
sum+=*(iter1);
ivec2.push_back(sum);
}
ivec2.push_back(*iter1);
}
cout<<"The final result is:"<<endl;
vector<int>::iterator iter2=ivec2.begin();
while (iter2!=ivec2.end())
{
cout<<*iter2<<endl;
++iter2;
}
return 0;
}
我使用了迭代器来完成这道题,上述程序经运行知能达到所要求的效果。但是上面的for循环表达式:
sum=*(iter1);
++iter1;
sum+=*(iter1);
我觉得有些繁琐,最初,我想通过:sum=*iter+*(++iter); 这句话来实现,但是结果出现错误,举例如下:
向左转|向右转看到这种结果,我认为是表达式sum=*iter+*(++iter)遵循了从右至左的结合顺序,先完成++iter,在完成值得和运算。接着,我想按照从右至左的结合顺序这一规则,调整了表达式,
即:sum=*(++iter1)+*iter1;但是,经运行仍然得到上述一模一样的结果。我不知道这是为什么。我是一个C++初学者,希望热心的朋友能够帮我解答一下这个问题的原因。
另外,我还有一个问题,ivec1.size是否也可以用迭代器来表示,如ivec2.end()-1。行不行呢?谢谢。 展开
具体细节没看,不过对于sum=*iter+*(++iter)还是sum=*(++iter1)+*iter1这个问题,我已经回答很多遍了...这里跟你也说一下,千万不要这样写。这里除了求值顺序,还牵涉到一个顺序点的概念...
在C/C++中对顺序点的问题,在标准中是有规定的:
当遇到顺序点时,语言要求这一时刻的求值和副作用全部完成。(顺序点和副作用看下面链接)
在两个顺序点之间,子表达式求值和副作用的顺序是不同步的。
第一点是说,当遇到相应的顺序点(如;,等等都是顺序点,也可以叫做运算的结算点),应该把要处理的计算处理好,比如a=i++;b=++i;当遇到;时,此时的i++的值必须改变完成,才能继续执行。不然就无法得知++i的值到底是由哪一个i值改变而来。
而第二点则是你这题里的问题。也就是说再两个结算点之间,各个子计算的副作用是无法确定谁先谁后的,这跟求值顺序无关,依赖于编译器的实现。
也就是说,比如a=++i+i++这个表达是,a的值到底是多少是未定义行为,谁也不知道结果会是多少,因为编译器可能会让++i先完成副作用再与i++进行相加(我这里说的是副作用发生顺序,不是求值的顺序),也可能会让i++的副作用先完成,这谁都是不知道的。
你可能会问,为什么C/C++不会把这个问题规定死?那是因为,C/C++把这个问题交给编译器的开发商,让编译器来进行语言优化,更好的处理这个问题,所以这样一来不同的编译器就有不同的结果了。再正式开发中,这种未确定行为是绝对不能写的。java中倒是规定了这个问题,但带来的结果就是编译器无法得到很好的优化。
至于你的第二点,ivec2.end()返回的是迭代器(相当于指针,即返回地址,加*后就是内容了),而size是vector的长度,两个是完全不同的东西。
最后再说一下,千万不要改成下面的写法,用你原来的写法就可以了,一点都不繁琐,简单清晰。如果一定要在一个表达式中用++i之类的语句,那么有副作用的语句只能有1个,而且这个变量只能出现一次。比如:a[i++]=b;或者a[b]=++i;只有这种语句能基本保证和你所想的一致的。(其实这种语句我觉得也不好,如果语句中出现了其他顺序点被你忽略了,比如逗号,也会出现问题。改成a[i]=b;i++;会好很多)
顺序点问题:http://www.cnblogs.com/dolphin0520/archive/2011/04/20/2022330.html