译者序:
这是一篇我所见过的关于指针的最好的入门级文章,它可使初学者在很短的时间内掌握复杂的指针操作。虽然,现在的JAVA、C#等语言已经取消了指针,但作为一个C++程序员,指针的直接操作内存,在数据操作方面有着速度快,节约内存等优点,仍是很多C++程序员的最爱。指针就像是一把良剑,就看你怎么去应用它!
有关这篇文章的技术性问题你可以写信给我:[email protected].同时我的另外两篇相关文章《模板Guide》和《STL Guide》也快完成,希望能对您有所帮助!Loading... ...
译者:万江(chinahai)
什么是指针?
其实指针就像是其它变量一样,所不同的是一般的变量包含的是实际的真实的数据,而指针是一个指示器,它告诉程序在内存的哪块区域可以找到数据。这是一个非常重要的概念,有很多程序和算法都是围绕指针而设计的,如链表。
开始学习
如何定义一个指针呢?就像你定义一个其它变量一样,只不过你要在指针名字前加上一个星号。我们来看一个例子:
下面这个程序定义了两个指针,它们都是指向整型数据。
&号读作“什么的地址”,它表示返回的是变量在内存中的地址而不是变量本身的值。在这个例子中,pNumberOne 等于some_number的地址,所以现在pNumberOne指向some_number。 如果现在我们在程序中要用到some_number,我们就可以使用pNumberOne。
我们来学习一个例子:
在这个例子中你将学到很多,如果你对指针的概念一点都不了解,我建议你多看几遍这个例子,指针是个很复杂的东西,但你会很快掌握它的。
这个例子用以增强你对上面所介绍内容的了解。它是用C编写的(注:原英文版是用C写的代码,译者重新用C++改写写了所有代码,并在DEV C++ 和VC++中编译通过!)
#include <iostream.h>
void main()
{
// 声明变量:
int nNumber;
int *pPointer;
// 现在给它们赋值:
nNumber = 15;
pPointer = &nNumber;
//打印出变量nNumber的值:
cout<<"nNumber is equal to :"<< nNumber<<endl;
// 现在通过指针改变nNumber的值:
*pPointer = 25;
通读一下这个程序,编译并运行它,务必明白它是怎样工作的。如果你完成了,准备好,开始下一小节。
陷井!
试一下,你能找出下面这段程序的错误吗?
#include <iostream.h>
int *pPointer;
void SomeFunction();
{
int nNumber;
nNumber = 25;
//让指针指向nNumber:
pPointer = &nNumber;
}
void main()
{
SomeFunction(); //为pPointer赋值
//为什么这里失败了?为什么没有得到25
cout<<"Value of *pPointer: "<<*pPointer<<endl;
}
#include <iostream.h>
int *pPointer;
void SomeFunction()
{
// 让指针指向一个新的整型
pPointer = new int;
*pPointer = 25;
}
void main()
{
SomeFunction(); // 为pPointer赋值
#include <iostream.h>
int *pPointer;
void SomeFunction()
{
// 让指针指向一个新的整型
pPointer = new int;
*pPointer = 25;
}
void main()
{
SomeFunction(); //为pPointer赋值
cout<<"Value of *pPointer: "<<*pPointer<<endl;
delete pPointer;
}
#include <iostream.h>
void AddFive(int Number)
{
Number = Number + 5;
}
void main()
{
int nMyNumber = 18;
#include <iostream.h>
void AddFive(int* Number)
{
*Number = *Number + 5;
}
void main()
{
int nMyNumber = 18;
cout<<"My original number is "<<nMyNumber<<endl;
AddFive(&nMyNumber);
cout<<"My new number is "<<nMyNumber<<endl;
}
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;
}
注意,&MyArray[0] 也可以简写成 MyArray ,都表示是数组的第一个元素地址。但如果写成pArray = &MyArray可能就会出问题,结果是 pArray 指向的是指向数组的指针(在一维数组中尽管与&MyArray[0]相等),而不是你想要的,在多维数组中很容易出错。
在数组中使用指针
一旦你定义了一个指向数组的指针,你该怎样使用它呢?让我们来看一个例子,一个指向整型数组的指针:
#include <iostream.h>
void main()
{
int Array[3];
Array[0] = 10;
Array[1] = 20;
Array[2] = 30;
int *pArray;
pArray = &Array[0];
cout<<"pArray points to the value %d\n"<<*pArray<<endl;
}
这一句是告诉编译器是删除整个数组而不一个单独的元素。千万记住了。
后话
还有一点要小心,别删除一个根本就没分配内存的指针,典型的是如果没用new分配,就别用delete:
常见问题解答
Q:为什么我在编译程序时老是在 new 和 delete语句中出现'symbol undefined' 错误?
A:new 和 delete都是C++在C上的扩展,这个错误是说编译器认为你现在的程序是C而不C++,当然会出错了。看看你的文件名是不是.cpp结尾。
Q:new 和 malloc有什么不同?
A:new 是C++中的关健字,用来分配内存的一个标准函数。如果没有必要,请不要在C++中使用malloc。因为malloc是C中的语法,它不是为面向对象的C++而设计的。
Q:我可以同时使用free 和 delete吗?
A:你应该注意的是,它们各自所匹配的操作不同。free只用在用malloc分配的内存操作中,而delete只用在用new分配的内存操作中。
引用(写给某些有能力的读者)
这一节的内容不是我的这篇文章的中心,只是供某些有能力的读者参考。
有些读者经常问我关于引用和指针的问题,这里我简要地讨论一下。
在前面指针的学习中,我们知道(&)是读作“什么的地址”,但在下面的程序中,它是读作“什么的引用”
int myFirstNumber = 25;
int mySecondNumber = 20;
int &myReference = myFirstNumber;
myReference = mySecondNumber;//这一步能使myReference 改变吗?
cout<<myFristNumber<<endl;//结果是20还是25?
当在类中操作时,引用的值必须在构造函数中设定,例:
总结
这篇文章开始可能会较难掌握,所以最好是多读几遍。有些读者暂时还不能理解,在这儿我再做一个简要的总结:
指针是一个指向内存区域的变量,定义时在变量名前加上星号(*)(如:int *number)。
你可以得到任何一个变量的地址,只在变量名前加上&(如:pNumber = &my_number)。
你可以用'new' 关键字动态分配内存。指针的类型必须与它所指的变量类型一样(如:int *number 就不能指向 MyClass)。
你可以传递一个指针到函数。必须用'delete'删除你动态分配的内存。
你可以用&array[0]而让指针指向一个数组。
你必须用delete[]而不是delete来删除动态分配的数组。
文章到这儿就差不多结束了,但这些并不就是指针所有的东西,像指向指针的指针等我还没有介绍,因为这些东西对于一个初学指针的人来说还太复杂了,我不能让读者一开始就被太复杂的东西而吓走了。好了,到这儿吧,试着运行我上面写的小程序,也多自己写写程序,你肯定会进步不小的!
本文地址:http://com.8s8s.com/it/it2319.htm