开篇:润墨网以专业的文秘视角,为您筛选了一篇C++中指针的研究与应用范文,如需获取更多写作素材,在线客服老师一对一协助。欢迎您的阅读与分享!
摘要:c++程序设计中的指针是一种数据类型,具有指针类型的变量称为指针变量,它是用来存放其他变量或对象的地址,能正确灵活地使用好指针可以给程序带来很优化的结构设计思想和很高的工作效率。
关键词:指针;数组;函数;对象
中图分类号: TP311 文献标识码:A文章编号:1009-3044(2011)14-3366-04
指针是地址形象化的表示,它的应用在C++编程中是一个非常重要而且很难理解的一个环节,通过学习我们知道一般的变量是用来记录数据而指针变量是用来记录地址的。
1 空指针
空指针是指在程序中不指向任何变量或对象的地址,它的值是NULL,与任何有效指针的值都不同。其中NULL是在中定义的一个宏,代表为0。
C++中指针的值不能是整型值,但空指针是个例外,即空指针的值可以是一个纯粹的零。
例如:int*pa=0;/*空指针*/
空指针的值并不必须是一个纯粹的零,在编程时定义空指针会给我们带来任意访问不同变量或地址的随机性,但无法对它进行取内容操作,只有在真正指向了一个有意义的地址后我们才能对它进行取内容运算。
2 指针与一般变量
使用指针时分清变量的地址、指针、指针变量的值之间的区别和联系至关重要。如:
inti=9;
int*p; /*指针变量*/
p=&a; /*p指向a的起始地址2000*/
我们知道指针的运算有①&:取地址运算符②*:指针指向运算符,如图1。
1)*p=9; /*取到a的值*/
2)&*p=2000/2001; /*指向运算后进行取地址*/
3)*&a=9; /*取地址即p再进行指向运算*/
3 指针与数组
C++规定数组名代表数组的首地址,即第一个元素的地址,当然指针也可以指向数组以后的内存单元,即支持指针加(含自增)或减(含自减)运算。如图2。
charstr[10];
char*p;
p=str;/* p指向数组的首地址*/
这样p=&str[0];与p=str;是等价的,而p+i和str+i代表地址指向str数组的第i个元素。
3.1 用指针引用数组元素
通过指针运算可以很方便地找到数组中的任意一个元素,达到引用数组元素的目的。
例1编程从键盘上输入若干个字符后统计所输入的字符个数。
#include
void main()
{intcount=0;
chara[200];
char*p;
cout
cin>>a;
p=a;/*指针p指向数组的首地址*/
while(*p!=’\0’)
{count++;
p++;}
cout
不用new函数定义动态数组而巧妙地用指针指向数组的首地址即p=a;这样通过判断*p!=‘\0’是否成立,一直到最后一个元素。这里要注意字符串存储时是以‘\0’来结束的,当指针指向数组时实际上是指向所输入的第一个字符,而字符串数组可以整体进行输入和输出像cin>>a等。
3.2 指针数组
指针数组是指数组中的每一个元素都为一个指针变量,如:
char*p[5] ={"tda","lhui","clang","fxia","zhcai"};/*定义指针数组*/
指针数组p中存储了5个成员,p[0]= "tda",而*p[0]=‘t’,同理p[1]= " lhui ",而*p[1]=‘l’, p[2]= " clang",而*p[2]=‘c’, p[3]= " fxia ",而*p[3]=‘f’, p[4]= " zhcai ",而*p[4]=‘z’,代表把字符串的地址赋给指针,这里p[i]就是个指针指向每行的第一个字符的地址,*(p[i]+j)就是第i+1行第j+1个元素。比二维数组要节约大量的存储单元处理更方便灵活。
例2按姓名排序。
voidmain( )
{char *p[ ] ={"tda","lhui","clang","fxia","zhcai"};
char*t;
inti,j,k,n=5;
for(i=0;i
{k=i;
for(j=i+1;j
if(strcmp(p[k],p[j])>0) k=j;
if(k!=i)
{t=p[i];p[i]=p[k];p[k]=t;}}
for(i=0;i
cout
}
在程序中不用改变字符串的位置而通过指针数组的指向改变达到对字符串的排序大大减少程序运行的时间复杂度。
4 指针与函数
在C++中每一个函数在编译时都有一个入口地址,指向函数入口地址的指针为函数指针。有了函数指针后,引用函数就如同引用其他类型变量一样。
4.1 函数指针作为函数参数
用函数指针作为函数参数可实现传址调用,即将函数名传给形参。
例3求 sin xdx、 cos xdx等定积分的问题。
#include
#include
doublef1(double x){ return sin(x); }
doublef2(double x){return cos(x);}
doublef3(double (*p)(double),double a,double b)
/*函数指针作为函数参*/
{ int i;
double h,sum=0;
h=(b-a)/10000;
for(i=1;i
{
sum+=(*p)(a+ h*i + h/2)*h;
}
return sum;
}
double mian()
{
doublef1(double);
doublef2(double);
cout
cout
return 0;
}
程序中也可以在函数f3中直接调用函数f1和f2,但我们发现用函数指针作为函数参数时调用f3只要给出不同的函数作为实参而不用修改f3的结构,这样更符合面向对象的程序设计思想。
4.2 用函数指针调用函数
C++中函数名代表函数的入口地址,可以用函数名赋值给一个指针变量即让指针指向一个函数,就可以通过指针变量来访问它所指向的函数。
例4求圆的面积。
#include
#define PI 3.14159
floatarea(floatx)
{ floatz;
s=PI*x*x;
returnz;}
floatmain( )
{
floatarea(float);
floatr,s;
cout
cin>>r;
s=(*p)(r);
cout
}
其中float(*p)( );是定义函数指针并返回实型的值,(*p)不能写为*p,否则就代表定义一个返回值为float的指针,p=area;p指针指向area( )的入口地址,调用*p就是调用area,因为它不能往下指向函数中的语句所以不能向指向数组指针一样支持*(p+1)运算。
5 指针与类
类是C++中抽象的数据类型,它是数据和函数的封装体,用它所定义的变量称之为对象。
5.1 对象指针
一个对象一旦被创建,系统就给它分配了一个存储地址,当指针变量指向对象的地址时称它为对象指针。
例5指针在类中的应用
#include
classA{
private:
intx;
public:
A(inti){x=i;}
intfun(int y){return(x+z)*y;}
intz;
};
voidmain( )
{ Aa(2);
intA::*pz; /*指向类数据成员的指针pz*/
pz=&A::z;
a.*pz=6;
int (A::*pf)(int); /*指向类成员函数的指针pf */
pf=A::fun;
A*p=&a; /*对象指针p*/
cout
}
用类A定义一个对象a,则对象a就具有类A所封装的性质,程序中分别定义了pz、pf、p三个指针变量, m. * pz=6;实际上是对pz所指向的数据成员赋值,等价于m.z=2;而(p一>*pf) (3)则通过对象指针p来调用指向类的成员函数的指针pf,等价于p―>fun(8),巧妙地使用对象指针,很方便地实现对象对类成员的访问。
5.2 this指针
this指针是编译系统自动产生的指向对象本身的指针,当一个对象被创建后它的每一个成员函数都可以使用this指针。
例6this指针的应用
#include
classA{
private:
int a, b;
public:
A( ){ a=0; b=0; }
A(int a, int b) { this.a=a;this.b=b; }/*使用this指针*/
voidcopy(A&);
void print( ){cout
};
void A::copy(A&x)
{ if (this = = &x) return;/*this是指向x对象的地址*/
this―>a=x.a;
this―>b=x.b;
}
voidmain()
{
Aa1, a2(3, 4);
a1.print( );
a1.copy(a2);
a1.print( );
}
当一个对象调用成员函数时,编译程序先将对象的地址赋给this指针,然后调用成员函数,每次成员函数存取数据成员时,隐含使用了this指针,而不常显式地使用this指针。在copy函数通过引用来实现给对象赋值,a1.copy(a2);目的就是把a2值赋给a1。
6 结束语
指针往往对初学者来说难度相当大,掌握了指针的应用会让我们在编程思想上升一个新的台阶,每一个学习和使用C++程序设计的人都应当深入认真学习指针的知识,在理论联系实践的基础上掌握指针的应用。
参考文献:
[1] 皮得常.C++程序设计教程[M].北京:机械工业出版社,2009.
[2] 钱能.C++语言程序设计教程[M].北京:清华大学出版社,2005.
[3] 李龙澍.C++程序设计[M].北京:清华大学出版社,2003.
注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文