何为指针?
指针基本上和其它的变量一样,唯一的一点不同就是指针并不包含实际的数据,而是包含了一个指向内存位置的地址,你可以在这个地址找到某些信息。这是一个很重要的概念,并且许多程序或者思想都是将指针作为它们的设计基础,例如链表。
开始
如何定义一个指针?呃,就像定义其它的变量一样,不过你还需要在变量名之前添加一个星号。例如,下面的代码创建了两个指向整数的指针:
int* pNumberOne;
int* pNumberTwo;
注意到变量名的前缀“p”了吗?这是编写代码的一个习惯,用来表示这个变量是一个指针。
现在,让我们把这些指针指向一些实际的值吧:
pNumberOne = &some_number;
pNumberTwo = &some_other_number;
“&”标志应该读作“the address of(……的地址)”,它的作用是返回一个变量的内存地址,而不是这个变量本身。那么在这个例子中,pNumberOne就是some_number的地址,亦称作pNumberOne指向some_number。
现在,如果我们想使用some_number的地址的话,那么我们就可以使用pNumberOne了。如果我们希望经由pNumberOne而使用some_number的值的话,我们可以用*pNumberOne。“*”应该读作“the memory location pointed to by(由……指向的内存位置)”,它用来取得指针所指向的值。不过指针声明的情况例外,如“int *pNumber”。
到现在都学到什么了(一个例子):
咻!要理解的东西太多了,所以在此我建议,如果你还是不理解以上的概念的话,那么最好再通读一遍;指针是一个复杂的主题,要掌握它是要花些时间的。
这里有一个示例,解说了上面讨论的那些概念。它是由C编写成,并不带有C++的那些扩展。
#include
void main()
{
// 声明变量:
int nNumber;
int *pPointer;
// 现在,给它们赋值:
nNumber = 15;
pPointer = &nNumber; //“&”标志应该读作“the address of”,返回变量的内存地址
// 打印nNumber的值:
printf("nNumber is equal to : %d\n", nNumber);
// 现在,通过pPointer来控制nNumber:
*pPointer = 25;
// 证明经过上面的代码之后,nNumber的值已经改变了:
printf("nNumber is equal to : %d\n", nNumber);
}
请通读并编译以上代码,并确信你已经弄懂了它是如何工作的。然后,当你准备好了以后,就往下读吧!
陷阱!
看看你是否能指出以下程序的缺陷:
#include
int *pPointer;
void SomeFunction()
{
int nNumber;
nNumber = 25;
// 使pPointer指向nNumber:
pPointer = &nNumber;
}
void main()
{
SomeFunction(); // 让pPointer指向某些东西
// 为什么这样会失败?
printf("Value of *pPointer: %d\n", *pPointer);
}
这个程序首先调用SomeFunction函数,在其中创建了一个名为nNumber的变量,并且使pPointer指向这个变量。那么,这就是问题之所在了。当函数结束的时候,由于nNumber是一个本地变量,那么它就会被销毁。这是因为当语句块结束的时候,块中定义的本地变量都会被销毁。这就意味着当SomeFunction返回到main()的时候,那个变量就已经被销毁了,所以pPointer将会指向一个不再属于本程序的内存位置。如果你不懂这一点,那么你应该去读一读有关本地变量、全局变量以及作用域的东西,这些概念非常重要。
那么,如何解决这个问题呢?答案是使用一种名为动态分配的技术。请注意:在这一点上,C和C++是不同的。既然大多数开发者正在使用C++,那么下面的代码就使用C++来编写。
动态分配
动态分配也许可以算是指针的关键技术了。它被用于在没有定义变量的情况下分配内存,然后由一个指针指向这段内存。虽然这个概念好像很让人糊涂,其实它很简单。以下的代码解说了如何为一个整数分配内存空间:
1、指针是一种指向内存中某个位置的变量,你可以通过在变量名前添加星号(*)来定义一个指针(也就是int *number)。
2、你可以通过在变量名前添加“&”来获得它的内存地址(也就是pNumber = &my_number)。
3、除了在声明中以外(例如int *number),星号应该读作“the memory location pointed to by(由……指向的内存位置)”。指针所指向的值,而不是内存地址。
4、除了在声明中以外(例如int &number),“&”应该读作“the address of(……的地址)”。
5、你可以使用“new”关键字来分配内存。
6、指针必须和它所指向的变量类型相配套,所以int *number不应该指向一个MyClass。
7、你可以向函数传递指针。
8、你必须使用“delete”关键字来释放你分配的内存。
9、你可以使用&array[0]来获得一个数组的指针。
10、你必须使用delete[]来释放动态分配的数组,而不是简单的delete。
这并非一个完全的指针指南,其中有一点我能够涉及到的其它细节,例如指针的指针;还有一些我一点也未涉及到的东西,例如函数指针——我认为作为初学者的文章,这个有些复杂了;还有一些很少使用的东西,在此我亦没有提到,省得让这些不实用的细节使大家感到混乱。
就这样了!你可以试着运行本文中的程序,并自己编写一些示例来弄懂关于指针的问题吧。