资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,1,地址与指针,指针变量的定义和使用,指针与数组,指针数组,多维数组作为参数的通用函数,动态存储管理,定义类型,指向函数的指针,主要内容,二维,/,多维数组与指针的关系,指针(数值型,/,字符型)与一维数组,(数值型数组,/,字符串)的关系,2,4,指针数组(,用于处理二维数组或多个字符串),定义字符指针数组:,char*pa10;/,*pa,是数组,其元素是字符指针。*,/,优先级高,,char*string1,*string2,*string3,string1,string2,string3,指针,数组,指针数组:,数组的内容为指针,3,定义字符指针数组时用字符串常量提供,初始值,。:,char*days=Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,;,简单实例,:,printf(Work days:);,for(i=1;i6;+i),printf(%s,daysi);,printf(nWeekend:);,printf(%s%sn,days6,days0);,4,字符指针数组实例,:,char*keywords,=,auto,break,.,.volatile,while,;,char keywords329,=/*,定义和初始化*,/,auto,break,case,char,const,continue,defualt,do,double,else,enum,extern,float,for,goto,if,int,long,register,return,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile,while,;,5,两维字符数组与字符指针数组,不同,。定义:,char color16=RED,GREEN,BLUE;,char*color=RED,GREEN,BLUE;,指针数组与两维数组,6,void sort(char *name,int n);,print(char *name,int n);,int main(),char*name=Follow me,BASIC,Great Wall,FORTRAN,Computer;,int n=5;,sort(name,n);,print(name,n);,return 0;,void sort(char*name,int n),char*temp;,int i,j,k;,for(i=0;i n-1;i+),k=i;,for(j=i+1;j 0)k=j;,if(k!=i),temp=namei;namei=namek;namek=temp;,void print(char*name,int n),for(int i=0;i n;i+),printf(%sn,namei);,name0,name1,name2,name3,name4,name,Great Wall,FORTRAN,Computer,Follow me,BASIC,k,j,k,j,j,j,i=0,例 对字符串排序(简单选择排序)图解,1,地址交换,值不变,效率高,7,void sort(char *name,int n);,print(char *name,int n);,int main(),char*name=Follow me,BASIC,Great Wall,FORTRAN,Computer;,int n=5;,sort(name,n);,print(name,n);,return 0;,void sort(char*name,int n),char*temp;,int i,j,k;,for(i=0;i n-1;i+),k=i;,for(j=i+1;j 0)k=j;,if(k!=i),temp=namei;namei=namek;namek=temp;,void print(char*name,int n),for(int i=0;i n;i+),printf(%sn,namei);,name0,name1,name2,name3,name4,name,Great Wall,FORTRAN,Computer,Follow me,BASIC,k,k,j,j,j,i=1,k,例 对字符串排序(简单选择排序)图解,2,8,void sort(char *name,int n);,print(char *name,int n);,int main(),char*name=Follow me,BASIC,Great Wall,FORTRAN,Computer;,int n=5;,sort(name,n);,print(name,n);,return 0;,void sort(char*name,int n),char*temp;,int i,j,k;,for(i=0;i n-1;i+),k=i;,for(j=i+1;j 0)k=j;,if(k!=i),temp=namei;namei=namek;namek=temp;,void print(char*name,int n),for(int i=0;i n;i+),printf(%sn,namei);,name0,name1,name2,name3,name4,name,Great Wall,FORTRAN,Computer,Follow me,BASIC,k,k,j,j,i=2,例 对字符串排序(简单选择排序)图解,3,9,void sort(char *name,int n);,print(char *name,int n);,int main(),char*name=Follow me,BASIC,Great Wall,FORTRAN,Computer;,int n=5;,sort(name,n);,print(name,n);,return 0;,void sort(char*name,int n),char*temp;,int i,j,k;,for(i=0;i n-1;i+),k=i;,for(j=i+1;j 0)k=j;,if(k!=i),temp=namei;namei=namek;namek=temp;,void print(char*name,int n),for(int i=0;i n;i+),printf(%sn,namei);,name0,name1,name2,name3,name4,name,Great Wall,FORTRAN,Computer,Follow me,BASIC,k,k,j,i=3,例 对字符串排序(简单选择排序)图解,4,10,void sort(char *name,int n);,print(char *name,int n);,int main(),char*name=Follow me,BASIC,Great Wall,FORTRAN,Computer;,int n=5;,sort(name,n);,print(name,n);,return 0;,void sort(char*name,int n),char*temp;,int i,j,k;,for(i=0;i n-1;i+),k=i;,for(j=i+1;j 0)k=j;,if(k!=i),temp=namei;namei=namek;namek=temp;,void print(char*name,int n),for(int i=0;i prog1 there are five arguments,这时,prog1,是编号为,0,的命令行参数,,there,是编号,1,的命令行参数,,;共,5,个命令行参数。,指针数组处理多个字符串,13,main,开始执行时:,argc,是命令行参数的个数,argv,指向含,argc+1,个字符指针数组,前,argc,个指针指向各命令行参数串,最后有一个空指针,图为执行下面命令时,main,函数里的现场情况,prog1 there are five arguments,main,参数,常用,argc,、,argv,作为名字(实际上可以用其他名字)。参数类型确定。,14,例:写程序,echo,打印各命令行参数。写程序时不知道调用时的命令行参数是什么,但可以打印它们:,#include,int main(int argc,char*argv),int i;,for(i=0;i argc;+i),printf(Args%d:%sn,i,argvi);,return 0;,15,地址与指针,指针变量的定义和使用,指针与数组,指针数组,多维数组作为参数的通用函数,动态存储管理,定义类型,指向函数的指针,主要内容,二维,/,多维数组与指针的关系,16,5,二维(多维)数组作为函数参数,下面函数求出,n5,数组中数据均值(,n,是参数):,double aavg(int n,double a5),int i,j;,double sum=0.0;,for(i=0;i n;+i),for(j=0;j 5;+j),sum+=aij;,return sum/(5*n);,可用于任何,n5,的数组,但不能用于例如,47,的数组,本章,将介绍一种定义通用函数的方法。,作为函数参数时不必给出最左一维长度,但要求给出除最左一维外其他各维的长度。,17,解决方案:,考虑数组,int a108;,首元位置,&a00,。,每行,8,元素,第,1,行开始位置是:,&a00+8,访问第,1,行首元素用表达式:,*,(&a00+8),访问第,i,行首元素用表达式:,*,(&a00+i*8),访问,aij,:,*,(&a00+i*8+j),可见,有了一些信息后,可以算出元素的位置,18,处理两维数组所需信息:,1,)基本元素类型;,2,)数组两个维的长度;,3,)数组开始位置。,通过参数可得到数组的首元素位置和各维长。,打印数组,a,和另一,2036,的整型数组,mat,的调用形式:,prtMatrix(10,8,&a00,);,prtMatrix(20,36,&mat00,);,输出两维整型数组的函数,每行输出在一行。,void prtMatrix(int m,int n,int*mp,),int i,j;,for(i=0;i m;+i),for(j=0;j n;+j),printf(%d,*(mp+i*n+j),);,putchar(n);,用,prtMatrix(10,8,a,);,?,19,对二维数组,int a34,有,a-,二维数组的首地址,即第,0,行的首地址,a+i-,第,i,行,的首地址,ai,*(a+i)-,第,i,行第,0,列,的元素地址,ai+j,*(a+i)+j-,第,i,行第,j,列,的元素地址,*,(ai+j),*(*(a+i)+j),aij,a+i=&ai=ai=*(a+i)=&ai0,值相等,含义不同,a+i,&ai,表示第,i,行首地址,指向行,ai,*(a+i),&ai0,,,表示第,i,行第,0,列元素地址,指向列,int a34;,a0,a1,a2,2000,2008,2016,2000,2002,2008,2010,2016,2018,a0,0,a0,1,a1,0,a1,1,a2,0,a2,1,a0,2,a0,3,a1,2,a1,3,a2,2,a2,3,a,a+1,a+2,行指针与列指针,a00,a01,a02,a03,a10,a11,a12,a13,a20,a21,a22,a23,a,a+1,a+2,a0 a0+1 a0+2 a0+3,a,a+1,a+2,假定,int,型变量,大小为,2,字节,20,表示形式,含义,a,二维数组名,数组首地址,a0,*(a+0),*a,第,0,行第,0,列元素的地址,a+1,,,&a1,第,1,行首地址,a1,*(a+1),第,1,行第,0,列元素的地址,a1+2,*(a+1)+2,,,&a12,第,1,行第,2,列元素的地址,*(a1+2),*(*(a+1)+2),a12,第,1,行第,2,列元素的值,21,例指向二维数组元素的指针变量,int main(),static int a34=1,3,5,7,9,11,13,15,17,19,21,23;,int*p;,for(,p=a0;,p a0+12;,p+,),if(p-a0)%4=0)printf(n);,printf(%4d ,*p,);,return 0;,int a34;,a0,0,a0,1,a1,0,a1,1,a2,0,a2,1,a0,2,a0,3,a1,2,a1,3,a2,2,a2,3,p,22,int main(),int b23,*pb2,;,int i,j;,for(i=0;i 2;i+),for(j=0;j 3;j+),bij=(i+1)*(j+1);,pb0=b0;,pb1=b1;,for(i=0;i 2;i+),for(j=0;j 3;j+,pbi+,),printf(b%d%d:%2dn,i,j,*pbi,);,return 0;,int *pb2,pb0,pb1,int b23,b00 *pb0,b01 *(pb0+1),b02 *(pb0+2),b10 *pb1,b11 *(pb1+1),b12 *(pb1+2),1,2,3,2,4,6,例 用指针数组处理二维数组,23,定义形式:,数据类型,(,*,指针名,),一维数组维数,;,例,int (*p)4;,(),不能少,int(*p)4,与,int*p4,不同,p,的值是一维数组的,首地址,,p,是,行指针,可让,p,指向二维数组某一行,如,int a3,4,(*p),4,=a;,一维数组指针变量维数和,二维数组,列数,必须相同,指向一维数组的指针变量,int a34;,a0,0,a0,1,a1,0,a1,1,a2,0,a2,1,a0,2,a0,3,a1,2,a1,3,a2,2,a2,3,a,a+1,a+2,p,p+1,p+2,p0+1,或*,p+1,p1+2,或*,(p+1)+2,*(*p+1),或,(*p)1,*(*(p+1)+2),24,对*,(*(p+i)+j),的理解:,p+i,相当于,a,数组的第,i,行的首地址,;,*(p+i),相当于,a,数组的第,i,行第,0,个元素的地址,;,等价于,ai;,*(p+i)+j,相当于,a,数组第,i,行第,j,列的元素的地址,;,等价于,&aij,等价于,pi+j,等价于,ai+j,*(*(p+i)+j),等价于,aij,25,void fun(int(*p)3,int i),int k=0,j;,for(;k i;k+),for(j=0;j 3;j+),*(pk+j)=(k+1)*(j+1);,int main(),int a23,(*p)3;,p=a;,fun(p,2);,printf(,“,%dn,”,*(p1+2);,return 0;,运行结果:,6,例,1,分析以下程序的运行结果,26,int main(),int a34=1,2,3,4,3,4,5,6,5,6,7,8;,int i;,int,(*p)4=a,*q=a0;,for(i=0;i 3;i+),if(i=0),(*p)i+i/2=*q+1;,else,p+,+q;,for(i=0;i 3;i+),printf(%d,aii);,printf(%d,%dn,*(int*)p),*q);,return 0;,运行结果:,2,,,4,,,7,,,5,,,3,1,2,3,4,3,4,5,6,5,6,7,8,p,q,2,p,q,p,q,例,2,二维数组与指针运算,*,p,27,#include,void average(double *p,int n);,void search(double (*p)4,int n);,int main(),double score34=65,67,79,60,80,87,90,81,90,99,100,98;,average(*score,12);,search(score,2);,return 0;,void average(double*p,int n),double *p_end,sum=0,aver;,p_end=p+n-1;,for(;p=p_end;p+),sum+=(*p);,aver=sum/n;,printf(average=%5.2fn,aver);,void search(double (*p)4,int n),int i;,printf(No.%d:n,n+1);,for(i=0;i 1),+argv;,printf(%sn,*argv);,-argc;,31,例,2:,分析以下的程序,int main(),static int a5=1,3,5,7,9;,static int*num5=,int*p,i;,p=num;,for(i=0;i 5;i+),printf(“%dt”,*p);,p+;,return 0;,32,函数指针:函数在编译时被分配的入口地址用函数名表示,max,.,指令,1,指令,2,函数指针变量赋值,:,如,p,=,max;,指向函数的指针变量,定义形式:,数据类型,(,*,指针变量名,),(,参数表,);,如,int (*p)(int,int);,函数指针变量指向的函数必须有,函数说明,函数调用形式:,c=max(a,b);,c=,(*p),(a,b);,c=p(a,b);,对函数指针变量,p,n,p+,p-,无意义,(),不能省,int(*p)(),与,int *p(),不同,指针与函数,33,例 求,a,b,中的最小者,int min(int x,int y),return x,y?x:y);,int min(int x,int y),printf(“min=”);,return(x 0),/*y,与,y1,同符号,新区间,x,x2*/,x1=x;y1=y;,else x2=x;/*,异号,新区间,x1,x*/,while(fabs(y)=1E-6);/*,继续*,/,return x;,61,int main(),double x1,x2,x;,do,printf(“Input double x1,x2”);,scanf(“%lf%lf”,while(f(x1)*f(x2)0);,x=root(x1,x2);,printf(“root is%lf”,x);,return 0;,62,double cross(,MFP fp,double x1,double x2),double,y1=fp(x1),y2=fp(x2),;,return(x1*y2-x2*y1)/(y2-y1);,double root(,MFP fp,double x1,double x2),double x,y,y1=fp(x1);,do,x=cross(fp,x1,x2),;,y=fp(x);,if(y*y1 0.0)y1=y;x1=x;,else x2=x;,while(y=1E-6|y=-1E-6);,return x;,函数指针作为函数的参数,(,对比,P158,页,),求根问题:以函数指针作为求根函数的参数。重新定义弦线法求函数根的函数:,63,函数使用实例(设,fun,是类型合适的函数):,x=root(sin,0.4,4.5);,y=root(fun,1.26,7.03);,*fun,已经定义*,可以在函数头部直接描述函数指针参数,如:,double root(double(*fp)(double),.).,例:数值积分(自学),64,本章要点,指针的概念、定义和基本操作,指针作为函数参数。,指针与数组的关系,一维指针与一维数组的关系,一级、二级指针、指针数组、数组指针和二级数组的关系,指针运算(指针算术),动态存储分配,65,指针有什么用?,C,程序设计中使用指针可以,:,使程序简洁、紧凑、高效,有效地表示复杂的数据结构,动态分配内存,得到多于一个的函数返回值,66,Q&A!,这部分内容太多,复杂类型解读可以不讲,
展开阅读全文