正文

[ZT]VC++指针使用基础2007-01-05 14:04:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/otot/22271.html

分享到:

概述
    指针基本上和其它的变量一样,唯一的一点不同就是指针并不包含实际的数据,而是包含了一个指向内存位置的地址,你可以在这个地址找到某些信息。这是一个很重要的概念,并且许多程序或者思想都是将指针作为它们的设计基础,例如链表。

    定义一个指针,需要在变量名之前添加一个星号。例如,下面的代码创建了指向整数的指针:

int* pNumberOne;

    变量名的前缀“p”用来表示这个变量是一个指针。

pNumberOne=&some_number;

    “&”标志读作“the address of(……的地址)”,作用是返回一个变量的内存地址,而不是这个变量本身。
    如果希望由pNumberOne而使用some_number的值,可以用*pNumberOne。“*”读作“the memory location pointed to by(由……指向的内存位置)”,它用来取得指针所指向的值。不过指针声明的情况例外,如“int*pNumber”。 见下例:

#include
    void main()
    {
    int nNumber;
    int*pPointer;
    nNumber= 15;
    pPointer=&nNumber;
    printf("nNumber is equal to:%d\n", nNumber); //=15
    *pPointer= 25;
    printf("nNumber is equal to:%d\n", nNumber); //=25
    }

内存的动态分配
    动态分配是指针的关键技术。它用于在没有定义变量的情况下分配内存,然后由一个指针指向这段内存。以下的代码解说了如何为一个整数分配内存空间:

    int*pNumber;
    pNumber= new int; 

    第一行代码声明了一个指针pNumber,第二行代码分配了一个整数的空间,并使pNumber指向这一段新分配的内存。见下面完整例子

#include
    int*pPointer;
    void SomeFunction()
    {
    pPointer= new int;
    *pPointer= 25;
    }

    void main()
    {
    SomeFunction();//让pPointer指向某些东西
    printf("Value of*pPointer:%d\n",*pPointer);
    delete pPointer;
    }
 
最后一行的delete pPointer用于释放已分配的内存,你不将内存delete掉,你的程序就会得到一个“内存泄漏”。如果出现了内存泄漏,那么除非你关闭应用程序,否则你将无法重新使用这段泄漏的内存。但是尝试delete一段已经释放的内存是十分危险的,这可能会导致你的程序崩溃。

向函数传递指针
向函数传递指针的技术非常有用,见下面一段程序:

    #include
    void AddFive1(int Number) //得到Number的一个拷贝
    {
    Number= Number+ 5;
    }

    void AddFive2(int* Number) //得到Number的指针
    {
    *Number=*Number+ 5;  //操作Number数据本身
    }

    void main()
    {
    int nMyNumber= 18;
    printf("My original number is%d\n", nMyNumber); //=18
    AddFive1(&nMyNumber);
    printf("My new number is%d\n", nMyNumber); //=18
    AddFive2(&nMyNumber);
    printf("My new number is%d\n", nMyNumber); //=23
    }

    AddFive2函数中Number之前的“*”是告知编译器我们要在指针Number指向的数字上加5,而不是向指针本身加5。

    我们亦可以在函数中返回指针,像下面这个样子:

    int* MyFunction();

    在这个例子中,MyFunction返回了一个指向整数的指针。

指向类的指针
定义一个类:

    class MyClass
    {
    public:
    int m_Number;
    char m_Character;
    }; 

    然后定义一个MyClass的变量:

    MyClass thing; 

    也可以这样定义一个指向MyClass的指针:

    MyClass*thing; 

    然后,你可以为这个指针分配一些内存:

    thing= new MyClass; 

    因为thing并非一个MyClass,而是一个指向MyClass的指针,因此,我们必须使用一种不同的转换方式。将“.”(点)替换为一个“->”。请看下面这个例子: 
    class MyClass
    {
    public:
    int m_Number;
    char m_Character;
    };

    void main()
    {
    MyClass*pPointer;
    pPointer= new MyClass;
    pPointer->m_Number= 10;
    pPointer->m_Character='s';
    delete pPointer;
    }

指向数组的指针
    你也可以使指针指向数组,如下:
    int*pArray;
    pArray= new int[6]; 
    这将创建一个指针pArray,它会指向一个6个元素的数组。另一种不使用动态分配的方法如下:
    int*pArray;
    int MyArray[6];
    pArray=&MyArray[0]; 
见下例:
#include
    void main()
    {
    int Array[3];
    Array[0]= 10;
    Array[1]= 20;
    Array[2]= 30;
    int*pArray;
    pArray=&Array[0];
    printf("pArray points to the value%d\n",*pArray); //=10
    pArray++;
    printf("pArray points to the value%d\n",*pArray); //=20
    pArray++;
    printf("pArray points to the value%d\n",*pArray); //=30
    }
 
要想使指针移到数组的下一个值,我们可以使用pArray++。也可以pArray+ 2使这个数组指针移动两个元素。要注意的一点是,你必须清楚数组的上界是多少(在本例中是3),因为在你使用指针的时候,编译器不能检查出来你是否已经移出了数组的末尾。所以,你可能很容易地使系统崩溃。
数组的指针(例如int* pNumberSet),也可以看作一个数组。比如pNumberSet[0]相当于*pNumberSet,pNumberSet[1]相当于*(pNumberSet+ 1)。

如果用new为一个数组分配空间的话,就像下面这个样子:

    int*pArray;
    pArray= new int[6]; 
    delete[] pArray;//  那么必须这样释放它:

    delete之后的[]。这告知编译器它正在删除一个整个的数组,而不是单独的一个项目。你必须在使用数组的时候使用这种方法,否则可能会获得一个内存泄漏。

引用
    从某种角度上来说,引用不属于指针。引用和指针十分相似,在很多情况下用哪一个都可以。“&”读作“the address of(……的地址)”但在声明的时候例外。在声明的这种情况下,它应该读作“a reference to(……的引用)”,如下:

    int& Number= myOtherNumber;
    Number= 25; 

    引用就像是myOtherNumber的指针一样,只不过它是自动解析地址的,所以它的行为就像是指针指向的实际值一样。与其等价的指针代码如下:

    int* pNumber=&myOtherNumber;
    *pNumber= 25; 

    指针和引用的另一个不同就是你不能更换引用的内容,也就是说你在声明之后就不能更换引用指向的内容了。例如,下面的代码会输出20:

    int myFirstNumber= 25;
    int mySecondNumber= 20;
    int&myReference= myFirstNumber;
    myReference= mySecondNumber;
    printf("%d", myFristNumber); 

    当在类中的时候,引用的值必须由构造函数设置,像下面这种方法一样:

    CMyClass::CMyClass(int&variable): m_MyReferenceInCMyClass(variable)

    {
    //这里是构造代码
    }

引自http://mba.ce.cn/kao/ksit/itxxzn/200608/11/t20060811_8100388.shtml

阅读(4642) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册