资源描述
,任务9 指针的使用,目 录,上一页,下一页,返 回,VC+,1,1、掌握指针变量的定义,能正确引用指针变量,确定指针变量的指向;,2、掌握&和*运算符的使用及指针运算;,3、掌握指针作为函数参数的几种形式,能利用指针编写函数解决实际问题;,4、掌握使用指针处理数组及字符串的方法;,5、了解返回指针值的函数和main()函数的参数。,教 学 目 标,任务9-1,指针变量的定义与使用,一、指针与指针变量,1、获取变量的取地址,变量的地址指针,:系统根据变量的数据类型为其分配相应长度的存储空间,变量的存储空间在内存中的起始地址称为这个变量的地址,也称为指针。,取地址运算的一般形式,:&变量名,其中&是取地址运算符,是单目运算,右结合。,功能,:取其后变量的地址。,2、访问变量的两种方式,1,),直接访问,:通过变量名或变量的地址来访问变量的方式称为直接访问。,2,),间接访问,:把一个变量的地址存放到另一个变量中,通过对另一个变量的访问来访问这个变量,这种访问变量的方式称为间接访问。,2,例如:printf(%d,a);/*通过,变量名,*/,scanf(%d,&a);/*通过变量的,地址,*/,物品,钥匙,一个抽屉,另一个抽屉,2,2,3、指针变量,指针变量,:把存放地址的变量称为指针变量。指针变量的值为地址即指针。,指向,:如果指针变量p中存放的是变量a的地址,即指针变量p的值为变量a的地址,则称变量p指向变量a。,二、指针变量的定义,1、一般形式,存储类别 数据类型 *指针变量名;,2、说明,存储类别规定了指针变量的存储类别;,数据类型规定了指针变量所能指向的变量的类型,称为指针变量的,基类型,;,*表示后面的变量是指针变量,这是与普通变量定义的区别,。,3,返 回,例如:int *p;,p为指针变量,它的基类型为int,三、确定指针变量的指向,指针变量定义后,,必须确定指针变量的指向。,1,、,给,指针变量赋值,;,2,、,给,指针变量初始化,;,3,、,给指针变量赋空值,。,四、指针运算符,一般形式,: *指针变量,其中*为指针运算符,优先级别和结合方向与,&,相同。,作用,:求指针变量所指向的变量的值,即指针变量所指向的内存单元的内容。,说明,1,)如果,int,a,*p=&a,;,则,*,p,与,a,等价,即,*,p,也是一个变量,就是,p,所指向的变量;,2,)*与,&,互为逆运算;,3,),运算符“,*,”后面必须是指针变量,而不能是普通变量。,例如:int a,b5,*p,*q,*r,*s; float *t;,p=/*,确定p指向变量a,*/,t= /*,t的基类型与a不同,*/,q=b; /*,确定q指向数组b,相当于q=&b0,*/,r=a; /*,把a的值赋给r,*/,r=p;,/*,确定r指向p指向的变量a,*/,s=1000; /*,把1000赋给s,*/,s= /*,确定s指向数组元素b2,*/,t=s; /*,t与s的基类型不同,*/,例如: int a,*p=,相当于:int a,*p; p=,int *p=,int a3,*p=a,*q=,相当于:,int a3,*p,*q;p=a; q=,int a,*p,*q=p;,int a,*p=,例如: int a=3,*p=,printf(%d,%d,a,*p);,输出结果为:3,3,说明 *p与a 等价,如果,int a,*p=,则,*&a,=*(&a)=*p=,a,,,&*p,=&(*p)=&a=,p,。,即*&a=a,&*p=p,。,4,4,4,4,4,例如:int *p;,p=,NULL,;(或p=,0,;),其中,NULL,是一个符号常量,代表整数0,在stdio.h中定义。,此时,p是一个,空指针,,,不指向任何单元,。,注,:不能将一个非零数值赋给指针变量。,4,5,5,5,5,五、指针变量的引用,1,、,引用指针变量指向的变量,;,2,、,直接引用指针变量,。,例1,两个指针变量指向同一变量。,例2,交换两个指针变量的指向。,例3,交换两个指针变量所指向的变量的值。,六、指针运算,1,、对指向单元的相邻单元操作,指针不移动;,一般形式:指针变量+整型常量 指针变量-整型常量,2,、移动指针(指针自增或自减),一般形式:后缀形式:指针变量+ 指针变量- 前缀形式: +指针变量 -指针变量,注:加向后移动,减向前移动。后缀形式:“,先引用,后移动,”;前缀形式:“,先移动,后引用,”。,例4,指针变量作为循环变量向数组输入数据。,例如:int a=3,b=2,*p;,p=,a=a+b;,printf(%d,%dn,a,*p);,输出结果为:5,5,例3,交换两个指针变量所指向的变量的值。,程序:,#include stdio.h ,void,main(),int *p1,*p2,a,a1=10,a2=20;,p1=,printf(%d,%dn,*p1,*p2);,a=*p1;*p1=*p2;*p2=a;,printf(%d,%dn,*p1,*p2);,printf(%d,%dn,a1,a2);,输出结果:10,20,20,10,20,10,例2,交换两个指针变量的指向。,程序:,#include stdio.h ,void main(),int *p1,*p2,*p,a1=10,a2=20;,p1=,printf(%d,%dn,*p1,*p2);,p=p1;p1=p2;p2=p;,printf(%d,%dn,*p1,*p2);,printf(%d,%dn,a1,a2);,输出结果: 10,20,20,10,10,20,例1,两个指针变量指向同一变量。,程序:,#include stdio.h ,void main(),int *p1,*p2,a1,a2;,scanf(%d,%d,p1=,printf(%d,%dn,*p1,*p2);,p2=p1;,printf(%d,%dn,*p1,*p2);,运行情况:,10,20,10,20,10,10,例如: char a=ABC,*p=a;,printf(%s,p);,输出结果为:ABC,例如: int a=3,*p=,printf(%u,p);,输出为变量a的地址,5,5,5,例如:int a7=1,3,5,7,9,11,13,*p;,p=,printf(%3d,*(p+);,printf(%3d,*p+);,printf(%3d,(*p)+);,printf(%3d,*(+p);,printf(%3d,*+p);,printf(%3dn, +*p);,输出结果为:5 7 9 11 13 14,例如:int a5=1,3,5,7,9,*p;,p=,printf(,“,%2d,”,*p);,printf(,“,%2d,”,*(p+1);,printf(,“,%2d,”,*(p-2);,printf(,“,%2d,”,*p-1);,1000,1002,1004,1006,1008,1,3,5,7,9,p,p+1,p-1,p+2,p-2,a0,a1,a2,a3,a4,例4,指针变量作为循环变量向数组输入数据。,int a5,*p;,for(p=a;pa+5;p+),scanf(%d,p);,5,5,5,6,七、指向指针的指针,1、一级指针,非指针变量即普通变量的地址称为一级指针,存放普通变量的地址的指针变量称为一级指针变量。,2、二级指针,存放一级指针变量的地址的指针变量称为二级指针变量,即指向指针的指针。,3、二级指针定义的一般形式,存储类别 数据类型 *指针变量名;,4、说明,通常应该把一级指针的地址赋给二级指针,而不应把普通变量的地址赋给二级指针;,引用二级指针变量的值要用两个*;,定义二级指针变量也可以象,int *(*p),;这样来定义,即定义中的,*,也可以看成是运算符;,同样,可以定义多级指针。,6,6,例如:int *p,*q, a=3;,q=,p=,p=,例如:int *p,*q, a=3;,q=,p=,printf(%d,%d,%d,*p,*q,a);,输出结果为:3,3,3,说明*p,*q,a三者等价。,内存中的情况如下:,内存中的情况用图示表示如下:,&q,&a,3,p,q,a,7,7,7,7,7,7,任务9-2 指针作为函数参数,指针作为函数参数同数组名作为函数参数相同,都是地址传递。将变量的地址传给形参要求形参必须是指针变量,达到形参与实参变量共用存储单元的目的,从而实现通过被调函数来改变主调函数中变量的值,使一次函数调用返回“多个值”。,1、变量的地址作为实参,指针变量作为形参,例5,通过指针给变量赋值。,例6,变量的地址作为实参,指针变量作为形参,。,2、形参和实参都是指向同一类型的指针变量,例7,有10个整数,要求输出其中的最大数和最小数。,3、实参是数组名,形参是指针变量,例8,求一维数组中下标为奇数的元素之和。,4、实参是指针变量,形参是数组名,例9,求二维数组中全部元素之和。,例5 通过指针给变量赋值。,#include stdio.h,void main(),void sub(int *px,int *py);,int x,y;,sub(,printf( %d,%dn,x,y);,void sub(int *px,int *py),*px=10;*py=20;,例6,变量的地址作为实参,指针变量作为形参,。,#include stdio.h,void p(int x,int *y),int z;,z=x+*y;x=x+z;*y=*y+z;,printf(%2d,%2d,%2d,x,*y,z);,void,main(),int x=1,y=2,z=3;,p(x,printf(%2d,%2d,%2dn,x,y,z);,p(y,printf(%2d,%2d,%2dn,x,y,z);,例7 有10个整数,输出其中的最大数和最小数。,#include stdio.h,#define N 10,void,main() void max_min(int arr,int *q1,int *q2,int n);,int arrayN=1,8,10,2,-5,0,7,15,4,-5,*p1,*p2,a,b;,p1=,max_min(array,p1,p2,N);,printf( max=%d,min=%dn,a,b);,void max_min(int arr,int *q1,int *q2,int n),int i;*q1=*q2=arr0;,for(i=0;i*q1) *q1=arri;,if(arri*q2) *q2=arri;,例8 求一维数组中下标为奇数的元素之和。,#include stdio.h,void,main() int odd_add(int *p,int n) ;,static int a10=1,2,3,4,5,6,7,8,9,10,total;,total=odd_add(a,10);,printf(total=%dn,total);,int odd_add(int *p,int n) int *q=p,sum=0;,for(p+;pq+n;p=p+2) sum=sum+*p;,return(sum);,例9 求二维数组中全部元素之和。,#include stdio.h,#define M 3,#define N 4,void,main(),int arr_add(int arr,int n);,int aMN=1,3,5,7,9,11,13,15,17,19,21,23,*p,total;,p=a0;,total=arr_add(p,M*N);,printf(total=%dn,total);,int arr_add(int arr,int n),int i,sum=0;,for(i=0;i0) p=a0;a0=a1;a1=p;,if(strcmp(a0,a2)0) p=a0;a0=a2;a2=p;,if(strcmp(a1,a2)0) p=a1;a1=a2;a2=p;,for(i=0;i3;i+),printf(%sn,ai);,任务,9-4 用指针表示数组元素,通过定义一个指针指向数组元素来引用数组元素的方法称为指针法。,一、一维数组的元素表示法,1、地址法,:一维数组a中的元素ai用地址法(,见图,)可表示为:,ai*(a+i),下标运算符:,,优先级别最高,运算规则如上式。,2,、,指针法,设,a,是一维数组,,p,是一级指针变量。若,p=a;(,如图,),,则,ai,可用,p,表示为:,ai,*(,p+i,) ,pi,。,例,11,int,a=0,1,2,3,4,*p; p=a;,则下列哪项是对数组元素的正确引用。,例,12,下列程序找出数组中最大值和此元素的下标,数组元素的值由键盘输入,请从对应的选项中,选择正确的填入。,9,9,9,返 回,a0,a1,ai,an-1,a,数组,a,a+1,a+i,a+n-1,.,.,.,.,a0,a1,ai,an-1,a,数组,p,p+1,p+i,p+n-1,.,.,.,.,例如:,int a=0,1,2,3,4,*p=a;,printf(%d,%d,%d,%dn,a3,*(a+3),p3,*(p+3);,输出结果为:3,3,3,3,9,例11 int a=0,1,2,3,4,*p;,p=a;,下列哪项是对数组元素的正确引用,aB) *(-p),C,) *(p+2),D,) *(p-)E) a5,F,) p3,9,9,例12,下列程序找出数组中最大值和此元素的下标,数组元素的值由键盘输入,请从对应的选项中,选择正确的填入。,#include stdio.h,#define N 10,void,main(),int aN,*p,*s,i;,for(i=0;iN;i+),scanf(%d,(1),);,for(p=a,s=a;,(2),*s) s,=,(3),;,printf(max=%d,index=%dn,(4),(5),);,(1) A)*(a+i) B) p+i,C,) a+i D) pi,(2),A,) p-a B) s-a C) a-p D) a-s,(3),A,) p B) ap C) as D) a-p,(4) A) ap-a B) ap,C,) *s D) as,(5) A) p-a B) p,C,) s-a D) a-s,10,10,10,10,10,10,二、二维数组元素的表示法,1、地址法,:二维数组amn中的元素aij用地址法可表示为:,aij*(ai+j),*(*(a+i)+j),(*(a+i)j,注,:上式中的,(*(a+i)j,不能写成,*(a+i)j,。,2、指针法,用一级指针变量表示二维数组元素,设 int amn,*p;p=a0; (表示p指向a00)则二维数组a中的元素aij用p可表示为:,aij*(p+i*n+j)pi*n+j,(p,+i*n)j,用二级指针变量表示二维数组元素,设 int amn,*q,*p;q=a0;p=则二维数组a中的元素aij用p可表示为:,aij *(*p+i*n+j) *(pi+j) *,(*(p,+i)+j), (*(p+i)j pij,任务9-5 指针与函数,一、返回指针值的函数,一个函数被调用之后带回一个返回值给主调函数,这个值可以是整型、实型、字符型,也可以是指针类型。,1、定义的一般形式,数据类型 *函数名(形参表);,2、说明,1)由此定义的函数,函数的返回值是一个指针;,2)数据类型规定返回的指针指向的数据的类型。,例13,编写一个strcat()函数,它的作用是使一个字符串str2接到另一个字符串str1的后面,返回字符串str1的地址。,11,11,例13 程序如下:,#include stdio.h,#include string.h,char *strcat (char *str1,char *str2),char *p;,for (p=str1;*p!=0;p+);,while(*str2!=0),*p+=*str2+;,*p=0;,return str1;,void main(),char *strcat (char *str1,char *str2);,char *pt,str180,str240;,printf(请输入字符串str1:);,gets(str1);,printf(n请输入字符串str2:);,gets(str2);,pt=strcat(str1,str2);,printf(n连接后的字符串为:%sn,pt);,二、main()函数中的参数,在操作系统状态下,为了执行某个程序而键入的一行字符称为命令行,命令行一般以回车作为结束符,命令行中必须有程序的可执行文件名(.exe),此外,经常带有若干个参数,可执行文件名也称为命令名。,1,、命令行书写的一般形式,命令名 形参1 形参2,形参N,其中命令名与参数及参数与参数之间用空格分隔。,2、main()函数中的参数,main(),函数定义的一般形式,void main (,int,argc,,,char *,argv, ),12,12,例如:C:tc2copy li3-8.c xt5-2.c,13,说明,argc的值是命令行中所有参数(包括命令名)的个数 ;,指针数组argv中的各个指针分别指向命令行中的命令名和各个参数字符串。argv0指向命令名字符串,argv1指向参数1字符串,,,,argvN指向形参N字符串;,形参指针数组*argv也可用二级指针来代替,如:*argv;,形参argc和argv可由用户任意命名,但习惯上都使用上述名字。,参数传递过程,:,main(),函数中的参数通过命令行来传递,把命令行中参数的个数 传给,argc,,,把每个参数字符串的地址分别传给,argv0,argv1,argvN,。,
展开阅读全文