iterator与pointer的区别之一

来源:互联网 发布:华为ac6605的mac oid 编辑:程序博客网 时间:2024/06/06 02:17

编译环境:VC++6.0

程序代码如下:

#include <iostream>
#include <stdio.h>
#include <vector>
#include <list>


void test2()
{
    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值与预期的不同


原创粉丝点击