【文档说明】【C语言】第八章指针5课件.ppt,共(72)页,258.311 KB,由小橙橙上传
转载请保留链接:https://www.ichengzhen.cn/view-44453.html
以下为本文档部分文字说明:
【C语言】第八章指针58.5指向函数的指针1.指向函数的指针变量的定义2.返回指针值的函数3.用指向函数的指针作函数参数1指向函数的指针变量的定义函数的指针:一个函数占用一段内存单元,这段内存单元的起始地址称为函数的指针,用一指针变量指向函数,然后通过该指针变量可以实现函数
调用。定义一个指向函数的指针变量:类型标识符(*指针变量名)(形参表列);例如:int(*p)(int,int);定义p是指向函数的指针变量,它可以指向类型为整型且有两个整型参数的函数。p的类型用int(*)(int,int)表示函数返回值类型1指向函数的指针变量的定义
int(*p)(int,int);不能写成int*p(int,int)因为()的优先级高于*,后者表示p是一个函数,返回值为指向整型变量的指针。1指向函数的指针变量的定义例8.22用函数求整数a和b中的大者。解题
思路:定义一个函数max,实现求两个整数中的大者。在主函数调用max函数,除了可以通过函数名调用外,还可以通过指向函数的指针变量来实现。分别编程并作比较。示例(1)通过函数名调用函数#include<stdio.h
>intmain(){intmax(int,int);inta,b,c;printf("pleaseenteraandb:");scanf("%d,%d",&a,&b);c=max(a,b);printf(“%d,%d,max=%d\n",a,b,c);return0;}intm
ax(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}(2)通过指针变量访问它所指向的函数#include<stdio.h>intmain(){intmax(int,int);in
t(*p)(int,int);inta,b,c;p=max;printf("pleaseenteraandb:");scanf("%d,%d",&a,&b);c=(*p)(a,b);printf(“%d,%d,max=%d\n",a,b,c);re
turn0;}必须先指向,若写成p=max(a,b);错只能指向函数返回值为整型且有两个整型参数的函数总结:1.函数的调用可以通过函数名调用,也可以通过函数指针调用。2.(*p)()表示定义一个指向函数的指针变量,它不是固
定指向哪一个函数的,它是专门用来存放函数的入口地址的。3.函数名代表该函数的入口地址,因此p=max表示p指向函数max的入口。4.用函数指针变量调用函数时,只需用(*p)代替函数名即可。5.p+n,p++,
p--等运算无意义例8.23输入两个整数,然后让用户选择1或2,选1时调用max函数,输出二者中的大数,选2时调用min函数,输出二者中的小数。解题思路:定义两个函数max和min,分别用来求大数和小数。在主函数中根据用户输入的
数字1或2,使指针变量指向max函数或min函数。#include<stdio.h>intmain(){intmax(int,int);intmin(intx,inty);int(*p)(int,int);inta,b,c,n
;scanf("%d,%d",&a,&b);scanf(“%d”,&n);if(n==1)p=max;elseif(n==2)p=min;c=(*p)(a,b);printf("a=%d,b=%d\n",a,b);if(n==1)pr
intf("max=%d\n",c);elseprintf("min=%d\n",c);return0;}只看此行看不出调用哪函数intmax(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}
intmin(intx,inty){intz;if(x<y)z=x;elsez=y;return(z);}2.返回指针值的函数定义返回指针值的函数的一般形式为类型名*函数名(参数表列){函数体}例如int*fun();fun是函数名,调用它以后能得到一个指向整型数据的指针(地址)
。例8.25有a个学生,每个学生有b门课程的成绩。要求在用户输入学生序号以后,能输出该学生的全部成绩。用指针函数实现。解题思路:定义二维数组score存放成绩定义输出某学生全部成绩的函数search,它是返回指针的函数,形参是行指针和整型主函数将score和要找的学
号k传递给形参函数的返回值是&score[k][0](k号学生的序号为0的课程地址)在主函数中输出该生的全部成绩#include<stdio.h>intmain(){floatscore[][4]={{6
0,70,80,90},{56,89,67,88},{34,78,90,66}};float*search(float(*pointer)[4],intn);float*p;inti,k;scanf(“%d”,&k);printf("Th
escoresofNo.%dare:\n",k);p=search(score,k);for(i=0;i<4;i++)printf(“%5.2f\t”,*(p+i));printf("\n");return0;}返回k号学生课程首地址float*search(f
loat(*pointer)[4],intn){float*pt;pt=*(pointer+n);return(pt);}float*search(float(*pointer)[4],intn){float*pt;pt=*(pointer+n);re
turn(pt);}例8.26对例8.25中的学生,找出其中有不及格的课程的学生及其学生号。(课下自己看)3.用指向函数的指针作函数参数指向函数的指针变量的一个重要用途是把函数的地址作为参数传递到其他函数指向函数的指针可以作为函数参数,把函数
的入口地址传递给形参,这样就能够在被调用的函数中使用实参函数3.用指向函数的指针作函数参数……intmain(){……fun(f1,f2)……}voidfun(int(*x1)(int),int(*x2)(int,int)){inta,b,i=3,j=5;a=(*x1)(i);b=(*x2)(i,
j);}相当于a=f1(i);相当于b=f2(i,j);例8.24有两个整数a和b,由用户输入1,2或3。如输入1,程序就给出a和b中大者,输入2,就给出a和b中小者,输入3,则求a与b之和。解题思路:与例8.23相似,但现在用一个函数fun来实现以上功能。#include<stdio.h
>intmain(){voidfun(intx,inty,int(*p)(int,int));intmax(int,int);intmin(int,int);intadd(int,int);inta=34,b=-21,n;printf
("pleasechoose1,2or3:");scanf(“%d”,&n);if(n==1)fun(a,b,max);elseif(n==2)fun(a,b,min);elseif(n==3)fun(a,b,add);return0;}intfun(intx,in
ty,int(*p)(int,int)){intresout;resout=(*p)(x,y);printf(“%d\n”,resout);}intmax(intx,inty){intz;if(x>y)z=x;el
sez=y;printf("max=");return(z);}输入的选项为1时相当于max(x,y)intfun(intx,inty,int(*p)(int,int)){intresout;resout=(*p)(x,y);printf(“%d\
n”,resout);}intmax(intx,inty){intz;if(x>y)z=x;elsez=y;printf("max=");return(z);}输入的选项为2时相当于min(x,y)intfun(intx,inty,int(*
p)(int,int)){intresult;result=(*p)(x,y);printf(“%d\n”,result);}intmax(intx,inty){intz;if(x>y)z=x;else
z=y;printf("max=");return(z);}输入的选项为3时相当于add(x,y)intmin(intx,inty){intz;if(x<y)z=x;elsez=y;printf("min=");retu
rn(z);}intadd(intx,inty){intz;z=x+y;printf("sum=");return(z);}8.6指针数组和多重指针1什么是指针数组2指向指针数据的指针1什么是指针数组概念:
一个数组,其元素均为指针类型数据,称为指针数组。定义一维指针数组的一般形式为类型名*数组名[数组长度];int*p[4];例:inta=1,b=2,c=3,d=4;int*p[4];p[0]=&a
;p[1]=&b;p[2]=&c;p[3]=&d;P指针数组&a&b&c&dP[0]P[1]P[2]P[3]*p[0]等价于a1.什么是指针数组指针数组比较适合用来指向若干个字符串,使字符串处理更加方便灵活
可以分别定义一些字符串,然后用指针数组中的元素分别指向各字符串由于各字符串长度一般是不相等的,所以比用二维数组节省内存单元例8.27将若干字符串按字母顺序(由小到大)输出。"Follow""Great""FORTRAN""Computer"要考虑的问题
:1.数据的存储方式(普通变量,数组,常量)2.排序算法1.普通变量chars1,s2…;s1=„F‟;s2=„o‟……2.一维数组chars1[]={“Follow”};chars2[]={“Computer”};s3=…;s4=…;3.二维数组chars1[
][7]={“Follow”,“Great”,“FORTRAN”,“Computer”}4.常量存储字符串+4个指向字符串的指针变量char*p1=“Follow”;*p2=“Great”;*p3=…,*p4…;5.常量存储
字符串+一个指向字符串的指针数组char*p[]={“Follow”,“Great”,“FORTRAN”,“Computer”}#include<stdio.h>#include<string.h>intmain(){voidsort(
char*name[],intn);voidprint(char*name[],intn);char*name[]={“Follow”,“Great”,“FORTRAN”,“Computer”};intn=4
;sort(name,n);print(name,n);return0;}Follow\0Great\0FORTRAN\0Computer\0voidsort(char*name[],intn){cha
r*temp;inti,j,k;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(strcmp(name[k],name[j])>0)k=j;if(k!=i){temp=name[
i];name[i]=name[k];name[k]=temp;}}}Follow\0Great\0FORTRAN\0Computer\0name[0]name[1]name[2]name[3]voidsort(char*name[],intn
){char*temp;inti,j,k;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(strcmp(name[k],name[j])>0)k=j;if(k!=i){temp=name[i]
;name[i]=name[k];name[k]=temp;}}}Follow\0Great\0FORTRAN\0Computer\0name[0]name[1]name[2]name[3]i=0时执行后k变为3voidsort(char*name[],intn){char*temp;inti,
j,k;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(strcmp(name[k],name[j])>0)k=j;if(k!=i){temp=name[i];name[i]=name[k];
name[k]=temp;}}}Follow\0Great\0FORTRAN\0Computer\0name[0]name[1]name[2]name[3]voidsort(char*name[],intn){char*temp;inti,j
,k;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(strcmp(name[k],name[j])>0)k=j;if(k!=i){temp=name[i];name[i]=n
ame[k];name[k]=temp;}}}Follow\0Great\0FORTRAN\0Computer\0name[0]name[1]name[2]name[3]i=1时执行后k变为2voidso
rt(char*name[],intn){char*temp;inti,j,k;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(strcmp(name[k],name[j
])>0)k=j;if(k!=i){temp=name[i];name[i]=name[k];name[k]=temp;}}}Follow\0Great\0FORTRAN\0Computer\0name[0]name[1]name[2]name[3]voidsort(c
har*name[],intn){char*temp;inti,j,k;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(strcmp(name[k],name[j])>0)k=j;if(k!=i){temp=name[i
];name[i]=name[k];name[k]=temp;}}}Follow\0Great\0FORTRAN\0Computer\0name[0]name[1]name[2]name[3]i=2时执行后k变为3voidsort(char*name[],intn){
char*temp;inti,j,k;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(strcmp(name[k],name[j])>0)k=j;if(k!=i){temp=na
me[i];name[i]=name[k];name[k]=temp;}}}Follow\0Great\0FORTRAN\0Computer\0name[0]name[1]name[2]name[3]voidsort(ch
ar*name[],intn){char*temp;inti,j,k;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(strcmp(name[k],name[j])>0)k=j;if(k!
=i){temp=name[i];name[i]=name[k];name[k]=temp;}}}Follow\0Great\0FORTRAN\0Computer\0name[0]name[1]name[2]name[3]voidsort(char*name[],intn){char
*temp;inti,j,k;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(strcmp(name[k],name[j])>0)k=j;if(k!=i){temp=name[i];name[i
]=name[k];name[k]=temp;}}}Follow\0Great\0FORTRAN\0Computer\0name[0]name[1]name[2]name[3]voidprint(char*name[],intn){inti;for(i=0;i<n;i+
+)printf(“%s\n”,name[i]);}Follow\0Great\0FORTRAN\0Computer\0name[0]name[1]name[2]name[3]voidprint(char*name[]
,intn){inti;for(i=0;i<n;i++)printf(“%s\n”,name[i]);}voidprint(char*name[],intn){inti=0;char*p;p=name[0];wh
ile(i<n){p=*(name+i++);printf("%s\n",p);}}2.指向指针数据的指针在了解了指针数组的基础上,需要了解指向指针数据的指针变量,简称为指向指针的指针。inta=3;int*p1;int**p2
;p1=&a;p2=&p1;p2&p1p1&aa3问题:如何通过指针p2改变a的值,改为5答案:**p2=5例8.28、例8.29自己课下看8.6.3指针数组作main函数的形参指针数组的一个重要应用是作为main函数的形参。在以往的程序中,main函数的第一行一
般写成以下形式:intmain()或intmain(void)表示main函数没有参数,调用main函数时不必给出实参。这是一般程序常采用的形式。8.7.3指针数组作main函数的形参实际上,在某些情况下,main函数可以有参数,例如:intmain(intargc,c
har*argv[])其中,argc和argv就是main函数的形参,它们是程序的“命令行参数”。argv是*char指针数组,数组中每一个元素(其值为指针)指向命令行中的一个字符串。8.7.3指针数组作main函数
的形参通常main函数和其他函数组成一个文件模块,有一个文件名。对这个文件进行编译和连接,得到可执行文件(后缀为.exe)。用户执行这个可执行文件,操作系统就调用main函数,然后由main函数调用其他函数,从而完成程序的功能。8.7.3指针数组作main函数的形参
main函数的形参是从哪里传递给它们的呢?显然形参的值不可能在程序中得到。main函数是操作系统调用的,实参只能由操作系统给出。#include<stdio.h>intmain(intargc,char*argv[]){while(argc>1){++argv;pri
ntf(“%s\n”,*argv);--argc;}return0;}在VC++环境下编译、连接后,“工程”—“设置”—“调试”—“程序变量”中输入“ChinaBeijing”,再运行就可得到结果8.7动态内存分配与指向它的指针变量1.什么是内存的动态分配2.怎样建立内存的动态分配3.void指针
类型1.什么是内存的动态分配非静态的局部变量是分配在内存中的动态存储区的,这个存储区是一个称为栈的区域C语言还允许建立内存动态分配区域,以存放一些临时用的数据,这些数据需要时随时开辟,不需要时随时释放。这些数据是临时存放在一个特别的自由存储区
,称为堆区2.怎样建立内存的动态分配对内存的动态分配是通过系统提供的库函数来实现的,主要有malloc,calloc,free,realloc这4个函数。2.怎样建立内存的动态分配1.malloc函数其函数原型为void*malloc(unsignedintsize);其作用是在
内存的动态存储区中分配一个长度为size的连续空间函数的值是所分配区域的第一个字节的地址,或者说,此函数是一个指针型函数,返回的指针指向该分配域的开头位置2.怎样建立内存的动态分配malloc(100);
开辟100字节的临时分配域,函数值为其第1个字节的地址注意指针的基类型为void,即不指向任何类型的数据,只提供一个地址如果此函数未能成功地执行(例如内存空间不足),则返回空指针(NULL)2.怎样建立内存的动态分配2.calloc函数其函数原
型为void*calloc(unsignedn,unsignedsize);其作用是在内存的动态存储区中分配n个长度为size的连续空间,这个空间一般比较大,足以保存一个数组。用calloc函数可以为一维数组开辟动态存储空间,n为数组元素个数,每个元素长度为size。这就是动态数组
。函数返回指向所分配域的起始位置的指针;如果分配不成功,返回NULL。如:p=calloc(50,4);开辟50×4个字节的临时分配域,把起始地址赋给指针变量p2.怎样建立内存的动态分配3.free函数其函数原型为voidfree(void*p);其作用
是释放指针变量p所指向的动态空间,使这部分空间能重新被其他变量使用。p应是最近一次调用calloc或malloc函数时得到的函数返回值。2.怎样建立内存的动态分配free(p);释放指针变量p所指向的已分配的动态空间free函数无返回值
2.怎样建立内存的动态分配4.realloc函数其函数原型为void*realloc(void*p,unsignedintsize);如果已经通过malloc函数或calloc函数获得了动态空间,想
改变其大小,可以用recalloc函数重新分配。2.怎样建立内存的动态分配用realloc函数将p所指向的动态空间的大小改变为size。p的值不变。如果重分配不成功,返回NULL。如realloc(p,50);将p
所指向的已分配的动态空间改为50字节2.怎样建立内存的动态分配以上4个函数的声明在stdlib.h头文件中,在用到这些函数时应当用“#include<stdlib.h>”指令把stdlib.h头文件包含到程序文件中。2.怎样建立内存的动态分配3.v
oid指针类型void*p;定义了一个基类型为void的指针变量,它不指向任何类型的数据或指向空类型。int*p1;a=5;p1=&a;printf(“%d\n”,*p1);p=(void*)p1;printf(“%
d\n”,*p);错3.void指针类型例8.30建立动态数组,输入5个学生的成绩,另外用一个函放数检查其中有无低于60分的,输出不合格的成绩。(课下自己看)解题思路:用malloc函数开辟一个动态自由区域,用来存5个学生的成绩,会得到这个动态域第一个字节的地址
,它的基类型是void型。用一个基类型为int的指针变量p来指向动态数组的各元素,并输出它们的值。但必须先把malloc函数返回的void指针转换为整型指针,然后赋给p13.void指针类型#include<s
tdio.h>#include<stdlib.h>intmain(){voidcheck(int*);int*p1,i;p1=(int*)malloc(5*sizeof(int));for(i=0;i<5;i++)scanf("%d",p1+i);check(p1);return0;}
voidcheck(int*p){inti;printf("Theyarefail:");for(i=0;i<5;i++)if(p[i]<60)printf("%d",p[i]);printf("\n");}8.8有关指针的小结一有关指针的数据类型(假设#definen10)定义
含义inti;int*p;inta[n];int*p[n];int(*p)[n];intf();int*p();int(*p)();int**p;定义整型变量i。p为指向整型数据的指针变量。定义整型数组
a,它有n个元素。定义指针数组p,它由n个指向整型数据的指针元素组成。p为指向含n个元素的一维数组的指针变量。f为带回整型函数值的函数。p为带回一个指针的函数,该指针指向整型数据。p为指向函数的指针,该函数返回一个整型值。p是一个指针变量,它指向一个指向整型数据的指针变量。二指针运算小结1、指针
变量加(减)一个整数C规定,一个指针变量加(减)一个整数并不是简单地加(减)一个整数,而是将该指针变量的地址和它指向的变量所占的内存字节数相加(减)。即:p+i代表地址计算:p+i*d(d为一个变量所占字节数)2、指针变量赋值将一个变量地址赋给一个指针变量,而不能把一个整数赋给指针变量,
也不能把一个指针变量的值赋给一个整型变量。如:p=&a;p=array;p=&array[i];等p=100;i=p;错误3指针变量可以有空值,即该指针变量不指向任何变量。表示:p=NULL;NULL是整数0,p指向
地址为0的单元,所以先定义NULL,即:#defineNULL04两个指针变量可以相减两个指针变量指向同一个数组的元素,则两个指针变量之差是两个指针之间的元素个数,但两个指针变量之和无意义。5两个指针变量比较两个指针变量指
向同一个数组的元素,则可以进行比较。指向前面的指针变量小于指向后面的指针变量。若不指向同一个数组则比较无意义。