ImageVerifierCode 换一换
格式:DOCX , 页数:19 ,大小:26.89KB ,
资源ID:9364757      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/9364757.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(浙江大学刘加海C语言课件5.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

浙江大学刘加海C语言课件5.docx

1、浙江大学刘加海C语言课件5第5章 指针与函数 本章重点1. 函数指针的概念、定义及赋值。2. 函数指针的应用。3. 指针函数的定义。4. 命令行参数的应用。 本章难点1. 函数指针的概念,函数指针的赋值及调用方法。尤其是定义及调用中的形式参数及实际参数的使用。2. 指针函数的概念以及与函数指针的区别。3. 命令行参数编程中的文件名与命令的关系。4. 命令行参数的赋值方法。指针和函数的关系主要包括三个方面的内容:一是指针可以指向某个函数,即函数指针;二是函数的返回值可以是指针类型的变量,即指针函数;三是指针可以作为函数的参数。5.1 指向函数的指针大家知道,变量a被分配到某个存储区域,若指针变量

2、p的值为该存储区域的首地址,则称p为指向变量a的指针,通过对指针p的间接引用可以访问它所指向的变量a。函数虽然不是变量,但是它经过编译后,其目标代码在内存中是连续存放的,该代码的首地址就是函数执行时的入口地址,它可以赋给指针变量,使得指针变量指向函数。利用指向函数的指针变量,可以代替函数名,也可以作为函数的参数传递给其他函数。也就是说可以用指针变量指向基本类型变量、字符串、数组等,也可指向一个函数。一个函数在编译时被分配给一个入口地址。这个入口地址就称为函数的指针。可以用一个指针变量指向某函数,然后通过该指针变量调用此函数。5.1.1 用函数指针变量调用函数1函数指针的声明格式:数据类型 (*

3、指针变量名)(函数形参类型标识符列表);其中的“数据类型”是指函数返回值的类型。例如:char (*f1)(char *,char);int (*f2)(int *,int);上述语句声明两个指向函数的指针:f1指向形参类型依次为char*、char,返回值类型为char的函数;f2指向形参类型依次为int *、int,返回值类型为int的函数。注意f1、f2是不同类型的指针,因为它们各自所指向的函数的返回值类型,形参个数及各形参的类型不尽相同。2为指向函数的指针赋值函数名是指针常量,其值为该函数在内存中存储区域的首地址。只能将函数的首地址赋值到指向同类型函数的指针。函数指针赋值格式为:函数指

4、针函数名;3函数指针的调用方式为:(*指针名)(实在参数列表);5.1.2 用函数指针变量调用函数举例例5.1 用函数指针调用求最大值函数,求出a和b中的大者。函数占有一段内存单元,可用函数指针变量指向其首地址,通过指针变量来访问它所指向的函数。程序设计如下:#includeint max(int x,int y) return xy?x:y;void main()int a,b,c;int(*p)(int,int); /* 声明函数指针 */p=max; /* 函数名代表了函数入口地址 */scanf(%d,%d,&a,&b);c=(*p)(a,b); /* 调用方式 */printf(a=

5、%d,b=%d,max=%dn,a,b,c);注意(1) int(*p)(int,int);定义p是一个指向函数的指针变量,即所指向的函数返回值为int型,形参依次为int、int类型的函数。(2) 在int(*p)(int,int);(*p)两侧的括弧不可省略,表示p先与*结合,是指针变量,然后再与后面的( )结合,表示此函数指针变量所指向的函数返回值是整型。如果写成“int *p(int,int)”,则由于( )优先级高于*,它表示声明了一个函数,只不过这个函数的返回值是指向整型变量的指针。(3) 给函数指针变量赋值时只赋函数名,不准带参数。如:p=max;赋值语句“p=max;”的作用是

6、将函数max的入口地址赋给指针变量p。和数组名代表数组的起始地址一样,函数名代表函数的入口地址。 函数调用可以通过函数名,也可通过函数指针,本例中的调用形式为c=(*p)(a,b);用函数指针调用的参数与函数调用的参数完全一致,用函数指针变量调用函数时,只需将(*p)代替函数名即可。(4) 对指向函数的指针变量不准作加减运算,如:p+,p-,p+n都是错误的。例5.2 指向函数的指针简单应用示例。#includefloat f1(float x) return x*x;float f2(float x) return x*x*x;void main() float (*p)(float),y;

7、 p=f1; y=(*p)(2); printf(%fn,y); p=f2; y=(*p)(2); printf(%fn,y);其中,语句“p=f1;”将函数f1的首地址赋给p,表达式“(*p)(2)”的作用是以2为实参调用函数f1,返回值为4。同样,语句“p=f2;”将改写p的值为函数f2的首地址,表达式“(*p)(2)”的作用是以2为实参调用函数f2,返回值为8。思考:有二个函数定义:int add(int x,int y)return x+y;int sub(int x,int y)return x+y;在main函数中定义一个函数指针,分别调用函数add、sub,并在main函数中输出

8、结果。例5.3 已知契比雪夫多项式的定义如下: x (n=1)2x2-1 (n=2)4x3-3x (n=3)8x4-8x+1 (n=4)试编写程序,从键盘输入整数n和实数x,并计算多项式的值。#include void main()float fn1(float), fn2(float) ,fn3(float), fn4(float);float (*fp)(float);float x;int n;printf(input x:);scanf(%f,&x);printf(input n:);scanf(%d,&n);switch(n)case 1:fp=fn1;break;case 2:fp

9、=fn2;break;case 3:fp=fn3;break;case 4:fp=fn4;break;default:printf(data error!);printf(result=%f,(*fp)(x);float fn1(float x)return x;float fn2(float x)return 2*x*x-1;float fn3(float x)return 4*x*x*x-3*x;float fn4(float x)return 4*x*x*x*x-8*x*x+1;例5.4 设一个函数pp,在调用它的时候,每次实现不同的功能。输入a和b两个数,第一次调用pp时找出a和b中大

10、者,第二次找出a和b中小者。#includeint max(int,int); /函数原型声明int min(int,int); /函数原型声明void pp(int,int,int (*p)(int,int); /函数原型声明void main()int a,b;scanf(%d,%d,&a,&b);printf(max=);pp(a,b,max);printf(min=);pp(a,b,min);int max(int x,int y) /求x,y中的大者return xy?x:y;int min(int x,int y) /求x,y中的小者return xy?x:y;void pp(in

11、t x,int y,int (*p)(int,int)int result;result=(*p)(x,y);printf(%dn,result);运行情况如下:enter a and b:2,6max=6min=2注意:程序中使用的函数指针fp,将随着输入条件n的不同而指向不同的函数,从而达到在不同条件下调用不同函数的目的。5.2 返回值为指针的函数 函数被调用后,可以由函数中的return语句返回一个值到主调函数中。函数的返回值可以是整型值、字符值、实型值等,也可以是返回指针型的数据,即地址。返回值为指针的函数,与以前的函数概念类似,只是返回的值的类型是指针类型而已,此类函数通常称为指针函

12、数。指针函数定义形式:类型名 *函数名(形参表定义) 函数体如:int *func(int x,int y);其中,func是函数名,其返回值类型是“指向整型的指针”,也即函数值是一个指针,指向一个整型变量,函数的形参为int x 和int y。5.2.1 指针函数应用举例例5.5 由键盘输入112自然数,再调用指针函数输出英文名被调用程序中应定义指针函数。#includechar *month_name(int n)static char *name13=ILLEGAL,JANUARY,FEBRUARY,MARCH,APRIL,MAY,JUNE,JULY,AUGUST,SEPTEMBER,O

13、CTOBET,NOVEMBER,DECEMBER;return(n12)? name0:namen); void main() char *month_name(int); /*说明一个指针函数,由于函数定义在先,此语句可省略*/ int n; scanf(%d,&n); printf(%s,month_name(n);例5.6 编一函数,在一组字符串中找出按字典序最大的字符串。#include#includechar *find_max(char *str,int n) /声明函数返回值为指向字符的指针int i;char *p;p=str0; /假设str0及p所指向的字符串按字典序最大f

14、or(i=1;i0) p=stri; /使p指向按字典序最大的字符串return p; /返回指针值void main()char *a5=ABc,abc,Abc,abcd,abca;printf(%sn,find_max(a,5);运行结果:abcd分析:char *find_max(char *str,int n)声明函数返回值为一个指向字符或字符串的指针。形式参数char *str表示它是一个指针数组,指针数组中的每个元素相当于一个指针变量,分别指向不同字符串的首地址。strcmp(stri,p)表示stri和p指向的两个字符串从左至右逐个字符相比较(按ASCII码值大小比较),直到出现

15、不同的字符或遇到0为止。如果全部字符相同,则认为相等(返回0值);若出现不同的字符,则以第一个不相同的字符比较结果为准(返回其ASCII码的差值)。例5.7 有若干学生的成绩(每个学生四门课程),要求用户在输入学生序号(假设从0号开始)后,能输出该学生的全部成绩。#includefloat * search( float (*pointer)4, int n) ; /*函数原型声明 */void main()static float score4 =65,70,80,90,76,89,67,88,84,78,90,76 ;float *p;int i, num;printf(Enter the

16、 number of student:);scanf(%d,&num);printf(The scores of No.%d are:n, num); p = search(score, m); /* 在score数组中查询m号学生的成绩 */* p指向m号学生第0门课程*/for(i=0; i4; i+)printf(%5.2ft,*(p+i); float * search( float (*pointer)4, int n) float *pp; /* pp是指向实数的指针,pointer是指向数组的指针*/pp = *(pointer+n); /* pp = (float *)(poi

17、nter + n) */return pp; 运行结果如下: Enter the number of student:2 The scores of No.2 are: 84.00 78.00 90.00 76.00注意float(*pointer)4,其中的pointer是一个指向一维数组的指针变量,数组元素个数为4(四门课程),即pointer指向一个学生的四门成绩。main( )函数调用search函数,将score数组的首地址传给pointer(注意score是一个二维数组名,所以score也是一个指向行的指针,而不是指向列元素的指针)。输入学生序号后,使pp指向该学生第0门课程,赋值

18、给p。*(p+i)表示此学生第i门课程的成绩。例5.8 编一函数,在字符串中找出一个子串的首地址。#include#includechar *find_str(char *s1,char *s2)int i,j,ls2;ls2=strlen(s2); /求子串s2的长度ls2for(i=0;istrlen(s1)-ls2;i+) for(j=0;jls2;j+) if(s1j+i!=s2j) break; if(j=ls2) return s1+i; /* 查找s1+i是否为所求的地址值。具体思想为:从地址s1+i起的ls2个字符与从地址s2起的ls2个字符均对应相同,则s1+i是所求地址。

19、*/return NULL; / NULL为空指针void main()char *src=Windows98 Office97 Microsoft,*dest=Office97,*pp;pp=find_str(src,dest); /返回的地址值送给指针变量ppif(pp!=NULL) printf(%sn,pp);else printf(not find:%sn,dest);运行结果为:Office97 Microsoft注意 函数*find_str返回字符串s2在s1中第一次出现的首地址,当查找不到时返回空指针值NULL。5.2.2 指针函数和函数指针比较 指针函数和函数指针这两个概念都

20、是简称。它们的区别如表5.1所示。表5.1 函数指针和指针函数的区别函数指针指针函数含义:指向函数的入口地址的指针含义:调用函数后返回值为指针定义形式:类型 (*p)(形式参数表)定义形式:类型 *p(形式参数表)本质:指针本质:函数5.3 命令行参数5.3.1 命令行参数的概念所谓“命令行参数”,一般是在DOS环境下所输入的命令及其参数。执行文件的形式为:命令名 参数1 参数2 . 参数n(回车)。命令名和各参数之间用空格分隔。例如,若有一命令文件名为disp,现要将两个字符串“Zhejiang”,“Hangzhou”作为参数传送给main函数。可以写成以下形式: disp Zhejiang

21、 Hangzhou 带参数的命令行文件的编辑步骤:首先编辑一个名为disp.c(或disp.cpp)的文件,然后将之经过编译、连接后产生disp.exe文件,最后在Dos命令提示符下输入带参数的命令然后回车即可。5.3.2 命令行参数的表示方法在编辑C语言源程序时,main()函数应带有两个参数,形式为:void main(int argc, char *argv )注意 (1)形参argc是命令行中参数的个数,可执行文件名本身也算一个,以空格分隔。(2)形参argv是一个字符指针数组,argv是一个数组名,元素个数为形参argc的值,其元素为指向命令行字符串的指针,指针数组argvargc-

22、1分别指向命令行各参数的首地址。5.3.3 命令行参数使用举例例5.9 编一程序,显示命令行上的所有参数(不包括命令名),源程序名为echo.c。#include void main(int argc,char *argv)int i;i=0;while(argc1) +i; printf(%sn,argvi); -argc;编译连接后生成应用程序文件echo.exe,进入DOS环境,在命令行输入:dispZhejiangHangzhou运行结果为: Zhejiang Hangzhou程序运行时,系统自动作如下赋值:命令行参数的个数(含命令)3赋给argc,因为输入的参数为3个,分别为:dis

23、p zhejiang hangzhou。argv0指向字符串disp的首地址;argv1指向字符串Zhejiang的首地址;argv2指向字符串Hangzhou 的首地址。 思考:如文件名前有路径,它们都保存在argv0中,请调试当把+i放在printf语句后,程序的运行情况如何?例5.10 用一程序实现文件的加密和解密。约定:c程序取名为lock.c,程序的可执行文件名为lock.exe,其用法为:lock +|- ,其中“+”为加密,“-”为解密。#includevoid main(int argc, char *argv ) char c;if (argc != 3) printf(参数

24、个数不对!n);else c=*argv1; /*截取第二个实参字符串的第一个字符*/ switch(c) case +: /*执行加密*/ /*加密程序段*/ printf(执行加密程序段。n); break; case -: /*执行解密*/ /*解密程序段*/ printf(执行解密程序段。n); break; default: printf(第二个参数错误!n); 注意 (1)形参argc的值为3,因为有三个参数”lock”、”+|-“、被处理的文件名。(2)元素argv0指向第1个实参字符串“lock”,元素argv1指向第2个实参字符串“|”,元素argv2指向第3个实参字符串“被

25、处理的文件名”。(3)main函数中的形参不一定命名为argc和argv,可以是任意的名字,只是人们习惯用argc,argv而已。习 题1输入3个整数,按从小到大的顺序输出(用函数指针调用实现)。2输入3个字符串,按从小到大的顺序输出(用函数指针调用实现)。3用函数指针来实现:写一个程序,输入x的值,输出相应的结果。4从键盘输入10名学生的成绩,显示其中的最高分、最低分及平均成绩(要求用指针来编写程序)。5编制函数,在字符串数组中查找与另一个字符串相等的字符串,函数的返回值为字符串的地址或NULL值(当找不到时)。6以下程序输出的结果是( )。#include int funa( int a,

26、 int b) return a+b; int funb( int a, int b) return a-b; int sub( int (*t)(int ,int ) ,int x , int y)return (*t)(x,y); void main( )int x ,(*p)(int ,int);p = funa ; x = sub (p ,9 ,3);x += sub (funb,8,3);printf(%dn ,x) ;7阅读下面程序。#includevoid main(int a,char *ar )a-;printf(%d,a);if(a=0) exit(0);main( a ,ar); 如文件名为pro.c 编译后在命令行输入C:pro aaaaaa bbbbb cccc ddd ,写出程序运行的结果。8编一程序,输入星期的序号06,输出中文的星期名。9编写一个带命令行参数的程序prog.c。当运行prog filename时将文本文件filename按原样在标准输出(终端)上输出;当运行prog n filename时将文本文件按原样在标准输出(终端)上输出,并在各行开头显示当前行行号(从1:开始,如1:XXXXXXXX);其他运行方式均显示出错信息。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1