编译环境:VC++6.0
程序代码如下:
#include <iostream>#include <stdio.h>
#include <vector>
#include <list>
{
int a[]={1,3,4};
int *k = a;
list<int> list1;
list1.push_back(a[0]);
list1.push_back(a[1]);
list1.push_back(a[2]);
list<int>::iterator i = list1.begin();
cout<<"Iterator:"<<endl;
i = list1.begin();
cout<<"(1) "<<*i;
cout<<"|"<<*i+++*i++<<endl;
i = list1.begin();
cout<<"(2) "<<*i<<"|"<<*i+++*i++<<endl;
cout<<"Pointer:"<<endl;
cout<<"(1) "<<*k;
cout<<"|"<<*k+++*k++<<endl;
k = a;
cout<<"(2) "<<*k<<"|"<<*k+++*k++<<endl;
k = a;
printf("(3) printf: %d|%d\n",*k,*k+++*k++);
}
int main(int argc, char* argv[])
{
test2();
return 0;
}
(1) Debug编译,优化级别为0,运行结果如下
Iterator:
(1) 1|4
(2) 4|4
Pointer:
(1) 1|2
(2) 4|2
(3) printf: 1|2
(2)Release编译,优化级别为2,运行结果如下
Iterator:(1) 1|4
(2) 4|4
Pointer:
(1) 1|2
(2) 4|2
(3) printf: 4|2
由此可得以下结论:
在VC++6.0编译环境下,当函数实参有iterator或pointer的后缀自增或后缀自减运算时
[1] 若为Debug编译,优化级别为0,
iterator的后缀自增或后缀自减运算是用类成员函数方式实现的,获得该成员函数返回值时iterator已移动,即在计算实参过程中iterator已移动;
而pointer要在函数获得全部实参后和调用前才进行自增或自减。
[2] 若为Release编译,优化级别为2,
iterator的结果如[1],
而pointer要在函数计算实参后和计算下一实参前才进行自增或自减。
所以使用list模板的iterator进行list的合并时,不必担忧如“*iterator++”的运算可能导致该迭代器失效的问题,具体请看list头文件。
此外,还务必小心如
int *k;
...
fun(*k,*k++);
cout<<*k<<','<<*k++<<endl; //语句1
printf("%d,%d",*k++,*k); //语句2
的代码,因为
[1] 优化级别会影响语句2,但不影响语句1,尤其是优化级别2时,语句2中*k++的结果不受影响,而*k的结果却受所有其它实参的影响且无论__stdcall还是__cdecl
[2] 在自定义函数时,__stdcall和__cdecl的选择会对带自增运算的iterator表达式的实参的计算有很大影响
所以,为了正确起见,勿将自增或自减运算用于函数实参,尤其是如*k++和*k同时用作实参的情况将可能导致函数所获得的*k值与预期的不同