善于利用指针-课件

上传人:痛*** 文档编号:242851933 上传时间:2024-09-08 格式:PPT 页数:216 大小:4.17MB
返回 下载 相关 举报
善于利用指针-课件_第1页
第1页 / 共216页
善于利用指针-课件_第2页
第2页 / 共216页
善于利用指针-课件_第3页
第3页 / 共216页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,*/21,第,8,章 善于利用指针,8.1,指,针,是什么,8.2,指针变量,8.3,通过指针引用数组,8.4,通过指针引用字符串,8.5,指向函数的指针,8.6,返回指针值的函数,8.7,指针数组和多重指针,8.8,动态内存分配与指向它的指针变量,8.9,有关指针的小结,8.1,指針是什么,如果在程序中定义了一个变量,在对程序进行编译时,系统就会给,该,变量分配内存单元,编译系统根据程序中定义的变量类型,分配一定长度的空间,例如,,VC+,为整型变量分配,4,个字节,对单精度浮点型变量分配个字节,对字符型变量分配个字节,8.1,指针,是什么,内存区的每一个字节有一个编号,这就是“,地址,”,它相当于旅馆中的房间号。,在地址所标,识,的内存单元中存放数据,这相当于旅馆房间中居住的旅客一样。,由于通过地址能找到所需的变量单元,我们可以说,,地址指向该变量单元,。,将地址形象化地称为“,指针,”,务必弄清楚存储单元的,地址,和存储单元的,内容,这两个概念的区别,例如:,int,i,=3,j=6,k;,printf,(“%,d”,i,);,通过变量名,i,找到,i,的地址,2000,,从而,从,存储单元,读,取,3,int,i,=3,j=6,k;,k=,i+j,;,从这里取,3,将,9,送到这里,从这里取,6,直接存取,int,i,=3,j=6,k;,定义特殊变量,i_pointer,将,i,的地址存到这里,间接存取,i_pointer,=&,i,;,*,i_pointer,=,50,;,50,i,2000,3,2000,i_pointer,*,i_pointer,2000,3,直接存取,间接存取,为了表示将数值送到变量中,可以有两种表达方法:,(1),将,3,直接送到变量,i,所标识的单元中,例如:,i=3;,(2),将,3,送到变量,i_pointer,所指向的单元(即变量,i,的存储单元),例如:,*,i_pointer,=3;,其中,*,i_pointer,表示,i_pointer,指向的对象,指向就是通过地址来体现的,假设,i_pointer,中的值是变量的地址,(2000),,这样就在,i_pointer,和变量之间建立起一种联系,即通过,i_pointer,能知道,i,的地址,从而找到变量,i,的内存单元,由于通过地址能找到所需的变量单元,因此说,地址指向该变量单元,将地址形象化地称为“指针”。意思是通过它能找到以它为地址的内存单元,一个变量的,地址,称为该变量的“,指针,”,例如,地址,2000,是变量的指针,如果有一个变量专门用来存放另一变量的地址(即指针),则它称为“,指针变量,”,i_pointer,就是一个指针变量。指针变量就是地址变量,用来存放地址的变量,指針变量的值是地址(即指针),“,指针,”和“,指针变量,”,是,不同的,概念,可以说变量,i,的指针是,2000,,而不能说,i,的指针变量是,2000,指针是一个地址,而指针变量是存放地址的变量,8.2,指针变量,8.2.1,使用指针变量的例子,8.2.2,怎样定义指针变量,8.2.3,怎样引用指针变量,8.2.4,指针变量作为函数参数,8.2.1,使用指针变量的例子,例,8.1,通,过指针变量访问整型变量。,解题思路:先定义,2,个整型变量,再定义,2,个指针变量,分别指向这两个整型变量,通过访问指针变量,可以找到它们所指向的变量,从而得到这些变量的值。,#include ,int,main(),int,a=100,b=10;,int,*,pointer_1,*,pointer_2;,pointer_1,=,pointer_2,=,printf(“a,=%,d,b,=%,dn”,a,b,);,printf,(“*pointer_1=%d,*pointer_2=,%,dn,”,*pointer_1,*pointer_2,);,return 0;,定义两个指针变量,使,pointer_1,指向,a,使,pointer_2,指向,b,直接,输出变量,a,和,b,的值,间接,输出变量,a,和,b,的值,#include ,int,main(),int,a=100,b=10;,int,*,pointer_1,*,pointer_2;,pointer_1,=,pointer_2,=,printf(“a,=%,d,b,=%,dn”,a,b,);,printf,(“*pointer_1=%d,*pointer_2=,%,dn,”,*pointer_1,*pointer_2,);,return 0;,此处,*,与,类型名,在一起。此时共同定义指针变量,此处,*,与指针变量一起使用。此时,代表指针变量所指向的变量,8.2.2,怎样定义指针变量,存储类型,基类型 *,指针变量名,;,上句定义了一个,指向基类型数据的指针变量,;,必须给出基类型,与指针变量的运算有关,.,不能用一个整数对指针变量赋值,.,int *pointer=2000; /,error,18,/216,存储类型,:,凡可声明普通变量的地方,都可声明指针变量,它可以是全局,静态全局,静态局部和局部的,.,数据类型,:,通常,每个指针都有一个类型,(void *,指针除外,),即定义中的,基类型,.,指针定义时会发生内存空间分配,.,指针在使用前,要进行初始化,;,指针忘了赋值比普通变量忘了赋值要危险得多,.,int *,iPtr,;,*,iPtr,=58;/,危险,!,建立一个指针,:,定义指针,给指针赋值,19,/216,8.2.3,怎样引用指针变量,在引用指针变量时,可能有三种情况:,给指针变量赋值。如:,p=,引用指针变量指向的变量,。,如,有,p=,则执行,printf(“%d,”,*p);,将输出,1,引用指针变量的值。如:,printf(“%o”,p,);,使,p,指向,a,*p,相当于,a,以,八,进制输出,a,的地址,8.2.3,怎样引用指针变量,变量的,指针,就是变量的地址,;,用来存放变量地址的变量是,指针变量,.,int i,*,i_pointer,;,i_pointer,=,&,i;,*,i_pointer,=3;,*,放在指针定义中,称为,指针定义符,;,其余时候,*,放在指针变量名之前,称为,间接引用符,.,21,/216,直接存取与间接存取,*,:,指针运算符,(,间接访问运算符,),&,:,取地址运算符,直接存取,(,访问,),方式,间接存取,(,访问,),方式,int i;,i=3;,int i,*,i_pointer,;,i_pointer,=,&,i;,*,i_pointer,=3;,例,:test8_1.c,22,/216,*和,&,若同时出现,作用相抵,:,int a=100,b=10;,int *pointer_1, *pointer_2;,pointer_1=,pointer_2=,pointer_2=,&*pointer_1,;,*&a,=50;,pointer_1,a,50,*和,&,同优先级,右结合,23,/216,/test8_1.cpp,#include ,using namespace std;,int,main(), float f=34.5; float*,fPtr,= /,浮点指针,int,*,iPtr,=(,int,*),/,warning,:,将浮点变量的地址赋给整型指针,cout,f,endl,iPtr,:,iPtr,*,iPtr,endl,fPtr,:,fPtr,*,fPtr,endl,endl,;,24,/216,*,iPtr,=*,fPtr,;,/,隐式类型转换,cout,f ,endl,*,iPtr,endl,*,fPtr,1107951616,fPtr:0x0067fdfc=34.5,4.76441e 44,34,4.76441e 44,指针具有一定类型,它是值为地址的变量,该地址是内存中另一个该类型变量 的存储位置,.,或者说,指针是具有某个类型的地址,.,25,/216,例,8.2,输入,a,和,b,两个整数,按先大后小的顺序输出,a,和,b,。,解题思路:用指针方法来处理这个问题。不交换整型变量的值,而是交换两个指针变量的值。,#include ,int,main(),int,*p1,*p2,*,p,a,b,;,printf(“integer,numbers:);,scanf(“%d,%d”,&a,&b,);,p1=,if(a,b), p=p1; p1=p2; p2=p; ,printf(“a,=%,d,b,=%,dn”,a,b,);,printf(“%d,%dn,”,*p1,*p2);,return 0;,a,b,p1,p2,p,5,9,&a,&b,成立,#include ,int,main(),int,*p1,*p2,*,p,a,b,;,printf(“integer,numbers:);,scanf(“%d,%d”,&a,&b,);,p1=,if(a,b), p=p1; p1=p2; p2=p; ,printf(“a,=%,d,b,=%,dn”,a,b,);,printf(“%d,%dn,”,*p1,*p2);,return 0;,a,b,p1,p2,p,5,9,&a,&b,&b,&a,#include ,int,main(),int,*p1,*p2,*,p,a,b,;,printf(“integer,numbers:);,scanf(“%d,%d”,&a,&b,);,p1=,if(a,b), p=p1; p1=p2; p2=p; ,printf(“a,=%,d,b,=%,dn”,a,b,);,printf(“%d,%dn,”,*p1,*p2);,return 0;,a,b,p1,p2,p,5,9,&a,&b,&b,&a,#include ,int,main(),int,*p1,*p2,*,p,a,b,;,printf(“integer,numbers:);,scanf(“%d,%d”,&a,&b,);,p1=,if(a,b), p=p1; p1=p2; p2=p; ,printf(“a,=%,d,b,=%,dn”,a,b,);,printf(“%d,%dn,”,*p1,*p2);,return 0;,a,b,p1,p2,p,5,9,&a,&b,&b,&a,可否改为,p1=,?,注意,:,a,和,b,的值并未交换,它们仍保持原值,但,p1,和,p2,的值改变了。,p1,的值原为,&a,,后来变成,&b,,,p2,原值为,&b,,后来变成,&a,这样在输出,*p1,和,*p2,时,实际上是输出变量,b,和,a,的值,所以先输出,9,,然后输出,5,8.2.4,指针变量作为函数参数,例,8.3,题目要求同例,8.2,,即对输入的两个整数按大小顺序输出。现用函数处理,而且用指针类型的数据作函数参数。,解题思路:定义一个函数,swap,,将指向两个整型变量的指针变量作为实参传递给,swap,函数的形参指针变量,在函数中通过指针实现交换两个变量的值。,#include ,int,main(),void,swap(int,*p1,int *p2);,int,a,b,;,int,*pointer_1,*pointer_2;,printf(please,enter a and b:);,scanf(“%d,%d”,&a,&b,);,pointer_1=,pointer_2=,if (ab) swap(pointer_1,pointer_2);,printf(“max,=%,d,min,=%,dn”,a,b,);,return 0;,a,b,pointer_1,5,9,&a,&b,pointer_2,void,swap(int,*p1,int *p2),int,temp;,temp=*p1;,*p1=*p2;,*p2=temp;,a,b,pointer_1,5,9,&a,&b,pointer_2,p1,&a,p2,&b,9,5,void,swap(int,*p1,int *p2),int,temp;,temp=*p1;,*p1=*p2;,*p2=temp;,void swap(,int,*p1,int *p2),int,*,temp;,*,temp=*p1;,*p1=*p2;,*p2=,*,temp;,危险!,无确定的指向,#include ,int,main(),if (ab),swap(,a,b,);,printf(“max,=%,d,min,=%,dn”,a,b,);,return 0;,void,swap(int,x,int,y,),int,temp;,temp=x; x=y; y=temp;,错!,无法交换,a,b,a,b,5,9,x,y,5,9,9,5,如果想通过函数调用得到,n,个要改变的值,:, 在主调函数中设,n,个变量,用,n,个指针变量指向它们, 设计一个函数,有,n,个指针,作,形参。在这个函数中,,,通过形参指针变量,改变它们所指向的,n,个变量的值, 在主调函数中调用这个函数,在调用时将这,n,个指针变量作实参,传,递,给该函数的形参, 在执行该函数的过程中,通过形参指针变量,改变它们所指向的,n,个变量的值,主调函数中就可以使用这些改变了值的变量,例,8.4,对输入的两个整数按大小顺序输出。,解题思路:尝试调用,swap,函数来实现题目要求。在函数中改变形参,(,指针变量,),的值,希望能由此改变实参,(,指针变量,),的值,#include ,int,main(),void,swap(int,*p1,int *p2);,int,a,b,;,int,*pointer_1,*pointer_2;,scanf(%d,%d,&a,&b,);,pointer_1=,if (ab) swap(pointer_1,pointer_2);,printf(max,=%,d,min,=%,dn,a,b,);,return 0;,void swap(,int,*p1,int *p2),int,*p;,p=p1; p1=p2; p2=p;,错!,只交换形参指向,注意:函数的调用可以(而且只可以)得到一个返回值(即函数值),而使用指针变量作参数,可以得到多个变化了的值。如果不用指针变量是难以做到这一点的。,要善于利用指针法。,例,8.5,输入,3,个整数,a,b,c,,要求按由大到小的顺序将它们输出。用函数实现。,解题思路:采用例,8.3,的方法在函数中改变这,3,个变量的值。用,swap,函数交换两个变量的值,用,exchange,函数改变这,3,个变量的值。,#include ,int,main(), void,exchange(int,*q1,int,*q2,int,*q3);,int,a,b,c,*p1,*p2,*p3;,scanf(%d,%d,%d,&a,&b,&c,);,p1=,exchange(p1,p2,p3);,printf(“%d,%d,%dn,a,b,c,);,return 0;,调用结束后不会改变指针的指向,void,exchange(int,*q1,int,*q2,int,*q3), void,swap(int,*pt1,int,*pt2);,if(*q1*q2) swap(q1,q2);,if(*q1*q3) swap(q1,q3);,if(*q2*q3) swap(q2,q3);,void,swap(int,*pt1,int,*pt2),int,temp;,temp=*pt1; *pt1=*pt2; *pt2=temp;,交换指针指向的变量值,8.3,通过指针引用数组,8.3.1,数组元素的指针,8.3.2,在引用数组元素时指针的运算,8.3.3,通过指针引用数组元素,8.3.4,用数组名作函数参数,8.3.5,通过指针引用多维数组,8.3.1,数组元素的指针,一个变量有地址,一个数组包含若干元素,每个数组元素都有相应的地址,指针变量可以指向数组元素(把某一元素的地址放到一个指针变量中),所谓数组元素的指针就是数组元素的地址,8.3.1,数组元素的指针,等价于,p=a;,第,i+1,个元素,:,ai,等价于 *,(,a+i,),等价于,pi,等价于 *,(,p+i,),第,i+1,个元素的地址,:,&,ai,等价于,a+i,等价于,&,pi,等价于,p+i,下标法,下标法,指针法,指针法,46,/216,8.3.2,在引用数组元素时指针的运算,在指针指向数组元素时,,允许,以下运算:,加一个整数,(,用,+,或,+=),,如,p+1,减一个整数,(,用,-,或,-=),,如,p-1,自加运算,如,p+,,,+p,自减运算,如,p-,,,-p,两个指针相减,如,p1-p2 (,只有,p1,和,p2,都指向同一数组中的元素时才有意义,),指针运算的进一步说明,:,指针可以进行,加减运算,(+,-,+,-).,指针的加减运算是,以基类型,(,即数据类型,),为单位,展开的,.,p+,或,+p,p-,或,-p,*p+,*+p,*p-,*-p,(*p)+,int a10,i=5,*p=&,ai,;,/p,指向,ai+1,即,p=&ai+1,/p,指向,ai-1,即,p=&ai-1,/,先*,p,得,ai,;,再,p=p+1,即,p=&ai+1,/,先,+p,即,p=,再*,p,得,ai+1,/,先*,p,得,ai,;,再,p=p-1,即,p=&ai-1,/,先,-p,即,p=,再*,p,得,ai-1,/,非指针运算,p,不变,等价于,ai,= ai+1,48,/216,8.3.3,通过指针引用数组元素,引用一个数组元素,可用下面两种方法:,() 下标法,如,ai,或,pi,() 指针法,如,*(,a+i,),或,*(,p+i,),其中,a,是数组名,,p,是指向数组元素的指针变量,其初值,p=a,8.3.3,通过指针引用数组元素,例,8.6,有一个整型数组,a,,有,10,个元素,要求输出数组中的全部元素。,解题思路:引用数组中各元素的值有,3,种方法:,(1),下标法,;,(2),通过数组名计算数组元素地址,找出元素的值,;,(3),用指针变量指向数组元素,分别写出程序,以资比较分析。,(1),下标法。,#include ,int,main(),int,a10;,int,i;,printf(“enter,10 integer numbers:n);,for(i,=0;i10;i+),scanf(%d,&ai,);,for(i,=0;i10;i+),printf(“%d,”,ai,);,printf(%n,);,return 0;,(2),通过数组名计算数组元素地址,找出元素的值,#include ,int,main(),int,a10;,int,i;,printf(“enter,10 integer numbers:n);,for(i,=0;i10;i+),scanf(%d,&ai,);,for(i,=0;i10;i+),printf(“%d,”,*(,a+i,);,printf(n,);,return 0;,scanf,(%,d,a+i,);,(3),用指针变量指向数组元素,#include ,int,main(),int,a10;,int,*,p,i,;,printf(“enter,10 integer numbers:n);,for(i,=0;i10;i+),scanf(%d,&ai,);,for(p,=,a;p,(a+10);p+),printf(“%d,”,*p);,printf(n,);,return 0;,for(p=,a;p,(a+10);p+),scanf,(%,d,p,);,for(p,=,a;a,(p+10);,a,+),printf(“%d,”,*,a,);,错!,3,种方法的比较:, 第,(1),和第,(2),种方法执行效率相同,编译系统是将,ai,转换为,*(,a+i,),处理的,即先计算元素地址。,因此用第,(1),和第,(2),种方法找数组元素费时较多。,3,种方法的比较:, 第,(3),种方法比第,(1),、第,(2),种方法快,用指针变量直接指向元素,不必每次都重新计算地址,像,p+,这样的自加操作是比较快的,这种有规律地改变地址值,(p+),能大大提高执行效率,3,种方法的比较:, 用下标法比较直观,能直接知道是第几个元素。,用地址法或指针变量的方法不直观,难以很快地判断出当前处理的是哪一个元素。,例,8.7,通过指针变量输出整型数组,a,的,10,个元素。,解题思路:,用指针变量,p,指向数组元素,通过改变指针变量的值,使,p,先后指向,a0,到,a9,各元素。,#include ,int,main(),int,*p,i,a10;,p=a;,printf(“enter,10 integer numbers:n);,for(i,=0;i10;i+),scanf(“%d”,p,+);,for(i,=0;i10;i+,p+),printf(“%d,”,*p);,printf(n,);,return 0;,退出循环时,p,指向,a9,后面的存储单元,因此执行此循环出问题,重新执行,p=a;,8.3.4,用数组名作函数参数,用数组名作函数参数,时,因为,实参数组名代表该数组首元素的地址,,,形参应该是一个指针变量,C,编译都是,将形参数组名作为指针变量来处理,的,int,main(), void,fun(int,arr,int,n);,int,array10;,fun (array,10);,return 0;,void,fun(int,arr, ,int,n),fun(,int,*,arr,int,n),int,main(), void,fun(int,arr,int,n);,int,array10;,fun (array,10);,return 0;,void,fun(int,*,arr,int,n),array0,arr0,array,数组,arr,array3,arr3,arr+3,实参数组名是指针常量,但形参数组名是按指针变量处理,在函数调用进行虚实结合后,它的值就是实参数组首元素的地址,在函数执行期间,,形参数组名,可以再被赋值,void fun (,int,arr, ,int,n),printf,(,%,dn, *,arr,);,arr,=arr+3;,printf,(,%,dn, *,arr,);,例,8.8,将数组,a,中,n,个整数按相反顺序存放,解题思路:将,a0,与,an-1,对换,将,a4,与,a5,对换。,j,i,例,8.8,将数组,a,中,n,个整数按相反顺序存放,解题思路:将,a0,与,an-1,对换,将,a4,与,a5,对换。,j,i,例,8.8,将数组,a,中,n,个整数按相反顺序存放,解题思路:将,a0,与,an-1,对换,将,a4,与,a5,对换。,j,i,例,8.8,将数组,a,中,n,个整数按相反顺序存放,解题思路:将,a0,与,an-1,对换,将,a4,与,a5,对换。,j,i,例,8.8,将数组,a,中,n,个整数按相反顺序存放,解题思路:将,a0,与,an-1,对换,将,a4,与,a5,对换。,j,i,#include ,int,main(), void,inv(int,x ,int,n);,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,);,printf(n,);,return 0;,void,inv(int,x ,int,n),int,temp,i,j,;,for(i,=0;in/2;i+), j=n-1-i;,temp=,xi;xi,=,xj;xj,=temp;,void inv(,int,x ,int,n),int,temp,*,i,*j;,i,=x; j=x+n-1;,for( ;,i,j;,i,+,j-), temp=*,i,; *,i,=*j; *j=temp; ,优化,例,8.9,改写例,8.8,,用指针变量作实参。,#include ,int,main(), void inv(,int,*,x,int,n);,int,i,arr,10,*p=,arr,;,for(,i,=0;i10;i+,p+),scanf,(“%,d”,p,);,inv(p,10);,for(p=,arr;p,arr+10;p+),printf,(“%d ”,*p);,printf,(n);,return 0;,不可少!,例,8.10,用指针方法对,10,个整数按由大到小顺序排序。,解题思路:,在主函数中定义数组,a,存放,10,个整数,定义,int,*,型指针变量,p,指向,a0,定义函数,sort,使数组,a,中的元素按由大到小的顺序排列,在主函数中调用,sort,函数,用指针,p,作实参,用选择法进行排序,#include ,int,main(), void,sort(int,x ,int,n);,int,i,*p,a10;,p=a;,for(i,=0;i10;i+),scanf(“%d”,p,+);,p=a;,sort(p,10);,for(p,=,a,i,=0;i10;i+),printf(“%d,”,*p); p+; ,printf(n,);,return 0;,void,sort(int,x,int,n),int,i,j,k,t,;,for(i,=0;in-1;i+), k=i;,for(j,=i+1;j,xk,) k=j;,if(k,!=i), t=,xi;xi,=,xk;xk,=t; ,void,sort(int,*,x,int,n),if (*(,x+j,)*(,x+k,) k=j;,t=*(,x+i,);*(,x+i,)=*(,x+k,);*(,x+k,)=t;,8.3.5,通过指针引用多维数组,指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素。但在概念上和使用方法上,多维数组的指针比一维数组的指针要复杂一些。,8.3.5,通过指针引用多维数组,1.,多维数组元素的地址,第,i+1,行,j+1,列的元素,:,aij,等价于 *,(*(,a+i)+j,),第,i+1,行,j+1,列的元素的地址,:,&,aij,等价于,*,(,a+i)+j,&a0,&a1,&a2,&a00 &a01,&a02 &a03,75,/216,8.3.5,通过指针引用多维数组,1.,多维数组元素的地址,int,a34=1,3,5,7,9,11,13,15,17,19,21,23;,1,3,5,7,9,11,13,15,17,19,21,23,a0,a1,a2,a,a+1,a+2,a0,a0+1,a0+2,a0+3,行指针,列指针,a,代表第,0,行首地址,a+1,代表第,1,行首地址,a+2,代表第,2,行首地址,1,3,5,7,9,11,13,15,17,19,21,23,a0,a1,a2,a,a+1,a+2,a0,a0+1,a0+2,a0+3,行指针,列指针,行指针每加,1,,走一行,a+i,代表行号为,i,的行首地址(按行变化),*(,a+i,),代表什么?,1,3,5,7,9,11,13,15,17,19,21,23,a0,a1,a2,a,a+1,a+2,a0,a0+1,a0+2,a0+3,行指针,列指针,相当于,a,i,a0,代表,a00,的地址,a0+1,代表,a01,的地址,a0+2,代表,a02,的地址,a0+3,代表,a03,的地址,1,3,5,7,9,11,13,15,17,19,21,23,a0,a1,a2,a,a+1,a+2,a0,a0+1,a0+2,a0+3,行指针,列指针,列指针每加,1,,走一列,a1,代表谁的地址?,a1+1,代表谁的地址?,a1+2,代表谁的地址?,a1+3,代表谁的地址?,1,3,5,7,9,11,13,15,17,19,21,23,a0,a1,a2,a,a+1,a+2,a0,a0+1,a0+2,a0+3,行指针,列指针,ai+j,代表谁的地址?,1,3,5,7,9,11,13,15,17,19,21,23,a0,a1,a2,a,a+1,a+2,a0,a0+1,a0+2,a0+3,行指针,列指针,代表,a,i,j,的地址,*(a,i,+j),代表什么?,代表元素,a,i,j,*(*(,a+i,)+j),代表什么?,与,*(a,i,+j),等价,例,8.11,二维数组的有关数据,(,地址和值,),#include ,int,main(),int,a34=1,3,5,7,9,11,13,15,17,19,21,23;,printf(“%d,%dn”,a,*a);,printf(“%d,%dn”,a0,*(a+0);,printf(“%d,%dn”,printf(“%d,%dn”,a1,a+1);,printf(“%d,%dn”,printf(“%d,%dn”,a2,*(a+2);,printf(“%d,%dn”,printf(“%d,%dn”,a10,*(*(a+1)+0);,printf(“%d,%dn,”,*a2,*(*(a+2)+0);,return 0;,printf(“%d,%dn”,a,*a);,printf(“%d,%dn”,a0,*(a+0);,printf(“%d,%dn”,printf(“%d,%dn”,a1,a+1);,printf(“%d,%dn”,printf(“%d,%dn”,a2,*(a+2);,printf(“%d,%dn”,printf(“%d,%dn”,a10,*(*(a+1)+0);,printf(“%d,%dn,”,*a2,*(*(a+2)+0);,return 0;,printf(“%d,%dn”,a,*a);,printf(“%d,%dn”,a0,*(a+0);,printf(“%d,%dn”,printf(“%d,%dn”,a1,a+1);,printf(“%d,%dn”,printf(“%d,%dn”,a2,*(a+2);,printf(“%d,%dn”,printf(“%d,%dn”,a10,*(*(a+1)+0);,printf(“%d,%dn,”,*a2,*(*(a+2)+0);,return 0;,2.,指向多维数组元素的指针变量,(1),指向数组元素的指针变量,例,8.12,有一个,34,的二维数组,要求用指向元素的指针变量输出二维数组各元素的值。,解题思路:,二维数组的元素是整型的,它相当于整型变量,可以用,int,*,型指针变量指向它,二维数组的元素在内存中是按行顺序存放的,即存放完序号为,0,的行中的全部元素后,接着存放序号为,1,的行中的全部元素,依此类推,因此可以用一个指向整型元素的指针变量,依次指向各个元素,#include ,int,main(),int,a34=1,3,5,7,9,11,13,15,17,19,21,23;,int,*p;,for(,p,=a0;pa0+12;p+,), if(p-a0)%4=0),printf(“n,”);,printf(“%4d”,*p);,printf(n,);,return 0;,控制换行,逐个访问各元素时常用此类指针,(2),指向由个元素组成的一维数组的指针变量,例,8.13,输出二维数组任一行任一列元素的值。,解题思路:假设仍然用例,8.12,程序中的二维数组,例,8.12,中定义的指针变量是指向变量或数组元素的,现在改用指向一维数组的指针变量。,#include ,int,main(),int,a3,4,=1,3,5,7,9,11,13,15,17,19,21,23;,int,(,*p,),4,i,j;,p=a;,printf(“enter,row and,colum,:);,scanf(“%d,%d”,&i,&j,);,printf(“a%d,%d,=%,dn,”,i,j,*(*(,p+i)+j,);,return 0;,a,i,j,p,为行指针,即数组指针,括号不能省,;,区别,:int *p4;/,指针数组,3.,用指向数组的指针作函数参数,一维数组名可以作为函数参数,多维数组名也可作函数参数。,用指针变量作形参,以接受实参数组名传递来的地址。,可以有两种方法:,用指向变量的指针变量,用指向一维数组的指针变量,例,8.14,有一个班,,3,个学生,各学,4,门课,计算总平均分数以及第,n,个学生的成绩。,解题思路:这个题目是很简单的。本例用指向数组的指针作函数参数。用函数,average,求总平均成绩,用函数,search,找出并输出第,i,个学生的成绩。,#include ,int,main(), void,average(float,*,p,int,n);,void,search(float,(*p)4,int n);,float score34=65,67,70,60,80,87,90,81,90,99,100,98;,average(,*score,12);,search(score,2);,return 0;,score00,的地址,void,average(float,*,p,int,n), float *,p_end,;,float sum=0,aver;,p_end,=p+n-1;,for( ;p=,p_end,; p+),sum=,sum,+(*p);,aver=sum/n;,printf(average,=%5.2fn,aver);,65,67,70,60,80,87,90,81,90,99,100,98,p,p_end,p+1,#include ,int,main(), void,average(float,*,p,int,n);,void,search(float,(*p)4,int n);,float score34=65,67,70,60,80,87,90,81,90,99,100,98;,average(,*score,12);,search(score,2);,return 0;,二维数组首行地址,void,search(float,(*p)4,int n),int,i;,printf(The,score of,No.%d,are:,n,n,);,for(i,=0;i4;i+),printf(%5.2f ,*(*(,p+n)+i,);,printf(n,);,65,67,70,60,80,87,90,81,90,99,100,98,p,p+2,例,8.15,在上题基础上,查找有一门以上课程不及格的学生,输出他们的全部课程的成绩。,解题思路:在主函数中定义二维数组,score,,定义,search,函数实现输出有一门以上课程不及格的学生的全部课程的成绩,形参,p,的类型是,float(*)4,。在调用,search,函数时,用,score,作为实参,把,score0,的地址传给形参,p,。,#include ,int,main(), void,search(float,(*p)4,int n);,float score34=65,57,70,60,58,87,90,81,90,99,100,98;,search(score,3);,return 0;,void,search(float,(*p)4,int n),int,i,j,flag,;,for(j,=0;j,n;j,+), flag=0;,for(i,=0;i4;i+),if(*(*(,p+j)+i,)60) flag=1;,if(flag,=1),printf(No.%d,failsn,j+1);,for(i,=0;i4;i+),printf(“%5.1f ”,*(*(,p+j)+i,);,printf(n,);,65,57,70,60,58,87,90,81,90,99,100,98,p,void,search(float,(*p)4,int n),int,i,j,flag,;,for(j,=0;j,n;j,+), flag=0;,for(i,=0;i4;i+),if(*(*(,p+j)+i,)60) flag=1;,if(flag,=1),printf(No.%d,failsn,j+1);,for(i,=0;i4;i+),printf(“%5.1f ”,*(*(,p+j)+i,);,printf(n,);,发现,不及格,,赋,1,若有,不及格,,则输出,不用,flag,,而用,break,语句,如何改程序?,8.4,通过指针引用字符串,8.4.1,字符串的引用方式,8.4.2,字符指针作函数参数,8.4.3,使用字符指针变量和字符数组的比较,8.4.1,字符串的引用方式,字符串是存放在字符数组中的。引用一个字符串,可以用以下两种方法。,(1),用字符数组存放一个字符串,可以通过数组名和格式声明“,%s,”输出该字符串,也可以通过数组名和下标引用字符串中一个字符。,(2),用字符指针变量指向一个字符串常量,通过字符指,针,变量引用字符串常量。,例,8.16,定义一个字符数组,在其中存放字符串“,I love China!,”,输出该字符串和第,8,个字符。,解题思路:定义字符数组,string,,对它初始化,由于在初始化时字符的个数是确定的,因此可不必指定数组的长度。用数组名,string,和输出格式,%s,可以输出整个字符串。用数组名和下标可以引用任一数组元素。,#include ,int,main(), char string=“I love China!”;,printf(“%sn”,string,);,printf(“%cn”,string7);,return 0;,string,string+7,例,8.17,通过字符指针变量输出一个字符串。,解题思路:可以不定义字符数组,只定义一个字符指针变量,用它指向字符串常量中的字符。通过字符指针变量输出该字符串。,#include ,int,main(), char *string=“I love China!”;,printf(“%sn”,string,);,return 0;,string,char *string;,string=” I love China!”;,#include ,int,main(), char *string=“I love China!”;,printf(“%sn”,string,);,string=”I am a student.”;,printf(“%sn”,string,);,return 0;,string,#include ,int,main(), char *string=“I love China!”;,printf(“%sn”,string,);,string=”I am a student.”;,printf(“%sn”,string,);,return 0;,string,例,8.18,将字符串,a,复制,给,字符串,b,,然后输出字符串,b,。,解题思路:定义两个字符数组,a,和,b,,用“,I am a student.,”对,a,数组初始化。将,a,数组中的字符逐个复制到,b,数组中。可以用不同的方法引用并输出字符数组元素,今用地址法算出各元素的值。,#include ,int,main(), char a =“I am a student.”,b20;,int,i;,for(i,=0;*(,a+i,)!=0;i+),*(,b+i,)=*(,a+i,);,*(,b+i,)=0;,printf(“string,a,is:%sn”,a,);,printf(string,b is:);,for(i,=0;bi!=0;i+),printf(“%c”,bi,);,printf(n,);,return 0;,printf,(string b is:%s,n“,b,);,例,8.19,用指针变量来处理例,8.18,问题。,解题思路:定义两个指针变量,p1,和,p2,,分别指向字符数组,a,和,b,。改变指针变量,p1,和,p2,的值,使它们顺序指向数组中的各元素,进行对应元素的复制。,#include ,int,main(),char a=I am a boy.,b20,*p1,*p2;,p1=a; p2=b;,for( ; *p1!=0; p1+,p2+),*p2=*p1;,*p2=0;,printf(“string,a,is:%sn”,a,);,printf(“string,b,is:%sn”,b,);,return 0;,8.4.2,字符指针作函数参数,如果想把一个字符串从一个函数“传递”到另一个函数,可以用地址传递的办法,即用字符数组名作参数,也可以用字符指针变量作参数。,在被调用的函数中可以改变字符串的内容,在主调函数中可以引用改变后的字符串。,8.4.2,字符指针作函数参数,例,8.20,用函数调用实现字符串的复制。,解题思路:定义一个函数,copy_string,用来实现字符串复制的功能,在主函数中调用此函数,函数的形参和实参可以分别用字符数组名或字符指针变量。分别编程,以供分析比较。,(1),用字符数组名作为函数参数,#include ,int,main(),void,copy_string(char,from,char,to);,char,a,=I am a teacher.;,char,b,=you are a student.;,printf(“a,=%,snb,=%
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!