概述 指针基本上和其它的变量一样,唯一的一点不同就是指针并不包含实际的数据,而是包含了一个指向内存位置的地址,你可以在这个地址找到某些信息。这是一个很重要的概念,并且许多程序或者思想都是将指针作为它们的设计基础,例如链表。 定义一个指针,需要在变量名之前添加一个星号。例如,下面的代码创建了指向整数的指针: 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

评论