资源描述
,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,第八章 善于利用指针,地址和指针的概念,变量的指针和指向变量的指针变量,数组与指针,字符串与指针,指向函数的指针,返回指针值的函数,指针数组和指向指针的指针,指针的数据类型和指针运算,指针,是语言中广泛使用的一种,数据类型,,运用指针编程是语言最主要的风格之一。,利用,指针变量,可以表示各种数据结构;能很方便地使用数组和字符串;并能象汇编语言一样,处理内存地址,,从而编出精练而高效的程序。,指针极大地丰富了语言的功能。学习指针是学习语言中,最重要,的一环,能否正确理解和使用指针是我们是否掌握语言的一个标志。,指针是语言中,最为困难,的一部分,在学习中除了要正确理解基本概念,还必须要,多思考,、,多比较,、,多编程,,,多上机,,在实践中掌握它。,学习指针的重要性,通常把存放数据的内存单元的地址称为,指针,。,在语言中,允许用一个变量来存放指针,这种变量称为,指针变量,。因此,一个指针变量的值就是某个内存单元的地,即:,一般变量用来存储变量的值;,指针变量,是用来保存变量地址的变量;变量的地址又称,变量的指针,,是一个常量。,定义指针变量的一般形式:,数据类型 *指针变量名;,若有:,char *pc;,则称指针变量,pc,是,char,型指针,pc=,/*&,取,c,的地址*/,则称指针变量,pc,指向变量,c,*pc,表示,pc,所指向的变量,即变量,c,一个指针变量只能指向,同一个类型,的变量,变量的指针和指向变量的指针变量,运算符,(单目 ),&,取变量的地址,2,*,取指针变量(所指向)的内容,2,例:,int,i=3;,int,*,i_pointer,=,(,注:,不允许把一个数赋予指针变量,),指针运算符,指针变量的引用,下面两个语句作用相同:,i=5;,*,i_pointer,=5;,例:输入,a,和,b,两个整数,按先大后小的顺序输出,a,和,b。,void main(),int,*,p1,*,p2,*,p,a,b,;,scanf(“%d,%d”,&a,&b,);,p1=,if(a,b)p=p1;p1=p2;p2=p;,printf(“na,=%,d,b,=%,dnn”,a,b,);,printf(“max,=%,d,min,=%,dn,”,*p1,*p2,);,运行情况如下:,5,9,a=5,b=9,max=9,min=5,指针变量的引用,例:用函数交换两个变量的值。,#,include,void main(),void,swap(int,*,px,int,*,py,);,int,a,b;,a=5;b=10;,printf,(before swap a=%d,b=%,dn,a,b);,swap(,&a,&b,);,/*,实参为变量,a,和,b,的地址*/,printf,(after swap a=%d,b=%,dn,a,b);,void,swap(int,*,px,int,*,py,),/*,形参为指向整型的指针*/,int,temp;,temp=,*,px,;,/*,将指针变量,px,的内容赋给变量,temp*/,*,px,=,*,py,;,/*,将指针,py,的内容赋给指针,px,的内容*/,*,py,=temp;,/*,将变量,temp,的值赋给指针,py,的内容*/,printf,(in swap x=%d,y=%,dn,*,px,*,py,);,指针变量作为函数参数,为了使在函数中改变了的变量值能被,main,函数所用,应该,用指针变量作为函数参数,,在函数执行过程中使指针变量所指向的变量值发生变化,函数调用结束后,这些变量值的变化依然保留下来。即,指针参数,使得被调用函数能够访问和修改主调函数中变量的值。,注意1:,下面的写法有问题,void,swap(int,*p1,int*p2),int,*temp;,*temp=*p1;,/*,此语句有问题*/,*,p1=*p2;,*p2=*temp;,注意2:,不能企图通过改变指针形参的值而使指针实参的值改变,void,swap(int,*p1,int*p2),int,*p;,p=p1;,p1=p2;,p2=p;,指针变量作为函数参数,例:,输入,a、b、c3,个整数,按大小顺序输出。,void,swap,(int,*,pt1,int*,pt2,),int,temp;,temp=*pt1;*pt1=*pt2;*pt2=temp;,void,exchange,(int,*,q1,int*,q2,int*,q3,),if(*q1*q2)swap(q1,q2);,if(*q1*q3)swap(q1,q3);,if(*q2*q3)swap(q2,q3);,void main(),int,a,b,c,*,p1,*,p2,*,p3,;,scanf(,“,%d,%d,%d,”,&a,&b,&c,);,p1=,exchange(p1,p2,p3);,printf(,“,n%d,%d,%dn,”,a,b,c,);,指针变量作为函数参数,在,C,语言中,指针和数组之间的关系十分密切,通过,数组下标,所能完成的任何操作都可以通过,指针,来实现。一般,用指针编写的程序执行速度快,但用指针实现的程序理解起来困难一些。,定义一个,指向数组元素,的指针变量的方法,与以前介绍的指针变量相同。,例如:,int,a10;,int,*p;/*,定义,p,为指向整型变量的指针*/,p=,/*,对指针变量赋值*/,C,语言规定,,数组名,代表数组的首地址,也就是第0号元素的地址。因此,下面两个语句等价:,p=,数组与指针,指向数组元素的指针,在定义指针变量时可以赋给初值:,int,*,p=,等价于:,int,*p;,p=,也可以写成:,int,*,p=a;,C,语言规定:如果指针变量,p,已指向数组中的一个元素,则,p+1,指向同一数组中的下一个元素。,引入指针变量后,就可以用两种方法来访问数组元素了。,如果,p,的初值为&,a0,则:,1,),p+i,和,a+i,就是,ai,的地址,或者说它们指向,a,数组的第,i,个元素,。,2,),*(,p+i,),或,*(,a+i,),就是,p+i,或,a+i,所指向的数组元素,即,ai,。,例如,*(,p+5),或*(,a+5),就是,a5。,3,),指向数组的指针变量也可以带下标,如,pi,与*(,p+i,),等价。,因此,引用一个数组元素可以用:,1),下标法,,即用,ai,形式访问数组元素。在前面介绍数组时都是采用这种方法。,2),指针法,,即采用*(,a+i,),或*(,p+i,),形式,用间接访问的方法来访问数组元素。,注意:,指针变量可以实现本身的值的改变。如,p+,是合法的;而,a+,是错误的。因为,a,是数组名,它是数组的首地址,是常量。,通过指针引用数组元素,例:输入和输出数组中的全部元素,void main(),int,a10,i;,for(i,=0;i10;i+),scanf(“%d”,&ai,);,for(i,=0;i10;i+),printf(“%d”,ai,);,*(,a+i,),for(p,=,a;p,(a+10);p+),printf(“%d,”,*p);,int,*p;,for(p,=,a;a,(p+10);a+),printf(“%d,”,*a);,注意,void main(),int,a10,i,*p;,p=a;,for(i,=0;i10;i+),scanf(“%d”,p,+);,p=a;,for(i,=0;i10;i+,p+),printf(“%d,”,*p);,通过指针引用数组元素,数组名或指针变量作函数参数,例:将数组,a,中,n,个整数按相反顺序存放。,void,inv(,int,x,int,n),int,temp,i,j,m,=(n-1)/2;,for(i,=0;i=,m;i,+),j=n-1-i;,temp=,xi;xi,=,xj;xj,=temp;,void main(),int,i,a10=3,7,9,11,0,6,7,5,4,2;,for(i,=0;i10;i+),printf(%d,”,ai,);,printf(“n,”);,inv(a,10);,for(i,=0;i10;i+),printf(“%d,”,ai,);,void,inv(,int,*,x,int,n),int,temp,m,=(n-1)/2;,int,*p,*i,*j;,i=x;j=x+n-1;p=,x+m,;,for(;i,=,p;i+,j,-),temp=*i;*i=*j;,*j=temp;,归纳起来,如果有一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下4种情况:,实参,形参,数组名,数组名,数组名,指针变量,指针变量,数组名,指针变量,指针变量,main(),int,a10;,f(a,10);,f(int,x,int,n),f(int,*,x,int,n),main(),int,a10,*p;,p=a;,f(p,10);,f(int,x,int,n),f(int,*,x,int,n),数组名或指针变量作函数参数,通过指针引用多维数组,设有整型二维数组,a34,的定义为:,int,a34=0,1,2,3,4,5,6,7,8,9,10,11,设数组,a,的首地址为1000,各下标变量的首地址及其值如图,语言允许把一个二维数组分解为多个一维数组来处理。因此数组,a,可分解为三个一维数组,即,a0、a1、a2,,每一个一维数组又含有四个元素。,多维数组的地址,从二维数组的角度来看,,a,是二维数组名,,a,代表整个二维数组的首地址,也是二维数组0行的首地址,等于1000。,a+1,代表第一行的首地址,等于1008。如图:,a,a0,*(a+0),*a,&a00,是相等的,,同理,,a+1,a1,*(a+1),&a10,是,相等,的。,a0,也可以看成是,a0+0,,是一维数组,a0,的0号元素的首地址,而,a0+1,则是,a0,的1号元素首地址,由此可得出,ai+j,则是一维数组,ai,的,j,号元素首地址,,它等于&,aij,。,由,ai,=*(,a+i,),得,ai+j,=*(,a+i)+j,。,由于*(,a+i)+j,是二维数组,a,的,i,行,j,列元素的首地址,所以,该元素的值等于,*(*(,a+i)+j,),。,例,:,已知,int,a34=1,2,3,4,5,6,7,8,9,10,11,12;,求:,A)*(a+1)+2,B)*(a0+6),C)*(a1+2),D)*(&a00+6),E,)*(,*(a+1)+2),即,a12,的地址,即,数组元素,a12,,,等于7,即,数组元素,a12,,,等于7,即,数组元素,a12,,,等于7,即,数组元素,a12,,,等于7,指向多维数组元素的指针变量,例:用指针变量输出数组元素的值,void main(),int,a34=1,3,5,7,9,11,13,15,17,19,21,23;,int,*p;,for(p,=a0;pa0+12;p+),printf(“%4d”,*p);,int,i,j,*p;,p=a0;,for(i,=0;i3;i+),for(j,=0;j4;j+),printf(“%4d”,*(,p+,i,*4+j,);,aij,在数组中的相对位置,又称为,数组指针,,其,说明形式,为,:,数据类型 (*指针变量名)常量表达式,例如:,int,(*pa)6;,含义:定义了一个指向数组的指针,被指向的数组是一,个,有6个元素的整型,一维,数组。,整数,整数,整数,整数,整数,整数,(*,pa)0,(*,pa)1,(*,pa)2,(*,pa)3,(*,pa)4,(*,pa)5,pa,指向由,m,个元素组成的一维数组的指针变量,注意:,pa+1,将指向下一个一维数组,pa+1,例:输出二维数组任一行任一列元素的值,void main()
展开阅读全文