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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

第10章指针的进一步讨论.docx

1、第10章 指针的进一步讨论第10章 指针的进一步讨论在第8章中已经对指针进行了讨论,介绍了指针和指针变量的概念,指针变量的定义、初始化和运算,一维数组和二维数组的指针,字符指针与字符串,以及指针作为函数参数等。在第9章中又介绍了结构体类型数据的指针及其用法。在C语言中,指针的用途非常广泛且用法非常灵活,本章将对指针进行进一步的讨论,主要介绍指针数组和指向指针的指针、函数的指针和指向函数的指针变量、返回指针值的函数等概念及其应用,以及用指针处理线性链表。10.1 指针数组与多级指针10.1.1 指针数组的概念及其应用1指针数组的概念指针数组是指每一个数组元素均用来存储一个指针值的数组,即指针数组

2、中的每一个元素都是指针变量。指针数组的定义形式为:类型标识符 *数组名数组长度;例如,语句:int *p5;定义了一个指针数组,数组名为p,共有5个元素,每个元素都是一个可以指向int型存储单元(或变量)的指针变量。注意它与第8章已介绍的指向一维数组的指针变量的定义形式上的区别。这里,运算符的优先级高于*,因此,p先与5结合,形成数组p5,然后p5再与*结合,*表示此数组是指针数组。指针数组的每一个元素(均为指针变量)的共同数据类型是“int *”。对于如下语句:int a45;定义的二维数组,我们知道,ai(0i4)均是指针,它指向二维数组元素ai0。因此我们可以用a0、a1、a3来初始化指

3、针数组p,语句如下:int *p4=a0, a1, a2, a3;这样,指针数组p的第i个元素pi(它与*(p+i)等价)就指向二维数组a的第i行的第0个元素ai0,pi+j则指向aij,因此,aij与*(pi+j)、*(*(p+i)+j)等价。如图10-1所示。注意:pi并不是指向二维数组a的第i行,而是指向第i行的第0个元素ai0。也就是说,pi仅是一个元素指针,而指向二维数组第i行的是一个行指针。2指针数组的应用指针数组特别适合于用来处理指向若干个字符串的问题,它将使字符串的处理更加方便灵活。例如,资料室有若干本书,每本书都有一个书名(可看成是一个字符串),我们可以采用二维字符数组来处理

4、该资料室的图书资料管理。定义二维字符数组并初始化如下:图10-1 指针数组的定义与初始化char c440=The C Programming Language, Database Design,Database System Implementation, Software Engineering;其存储形式如图10-2所示。利用二维数组来处理的缺点是每一本书的书名所占字节数(即二维数组的列数)相等。但实际上每一本书的书名(字符串)的长度是不相等的,二维数组的列数必须按最大字符串的长度来准备,造成许多内存单元的浪费。不仅浪费内存单元,而且在诸如字符串的排序等问题的处理上也较慢,因为它要将整个

5、字符串的内容进行交换。上述问题如果采用指针数组来处理,许多麻烦可以迎刃而解。首先我们可以定义一个字符指针数组book,然后让指针数组的每一个元素(均为指针变量)分别指向一个字符串,如图10-3所示。在第8章中我们已经介绍了通过指向字符的指针变量来处理字符串的问题。图10-3 利用指针数组处理字符串图10-2 利用二维数组处理字符串例10.1 对所有图书按字母顺序(由小到大)排序输出书名。#include #include void main() void sort(char *p, int), prn(char *p, int); / 声明被调用函数的原型char *book=The C Pr

6、ogramming Language, Database Design,Database System Implementation, Software Engineering;sort(book, 4); / 实参book是指针数组名prn(book, 4);void sort(char *p, int n) / 按升序对指针数组p所指向的字符串序列排序int i, j, minpost;char *t;for (i=0; in-1; i+) / 用选择法对字符串序列进行升序排序minpost=i;for (j=i+1; jn; j+)if (strcmp(pj, pminpost)0) m

7、inpost=j;if (minpost!=i) / 交换指针数组元素的指向t=pi; pi=pminpost; pminpost=t;void prn(char *p, int n) int i;for (i=0; in; i+)printf(%sn, pi);运行结果为:Database DesignDatabase System ImplementationSoftware EngineeringThe C Programming Language其中,排序函数sort实现字符串序列的升序排序,排序过程中,并没有真正移动字符串的存储,仅仅是通过交换指向字符串的指针来实现排序,最后,按指针

8、数组book中数组元素的顺序得到的字符串(即指针数组元素所指向的字符串)序列就是升序排序的。10.1.2 指针数组作main函数的形参在以前的程序中,主函数main()都是不带参数的。这是一般用户程序的特点。但在有些情况下(例如用C语言编写系统命令),当程序开始执行时,希望通过命令行将某些参数传递给程序,以控制程序的执行,这时main函数就需要带参数,以便来接受命令行的参数。命令行的一般形式为:命令名 参数1 参数2 参数带参数的main函数的一般格式如下:void main(int argc, char *argv) 按照约定,main函数可以带有两个名为argc和argv的参数。其中,ar

9、gc是int型参数,它接受的值是命令行参数的数目;argv是指向char型的指针数组参数,它的每个数组元素接受的值分别是指向命令行各参数字符串的指针。例如,有如下C程序:#include void main(int argc, char *argv) int i;for (i=1; iCProgram Please input number: 则形参argc的值为4,形参数组argv的值如图10-4所示。程序运行结果为:Please input number:图10-4 main函数的形参指针数组的指向10.1.3 行指针数组前面已经讨论了指针数组的概念。在第8章中我们还讨论过指向一维数组的指

10、针、指针变量,并分别简称为行指针、行指针变量。因此,行指针数组是指每一个数组元素都是存储行指针(即指向一维数组的指针)的数组,即指针数组中的每一个元素都是行指针变量。行指针数组的定义形式为:类型标识符 (*数组名指针数组长度)指向的数组长度;例如,语句:int (*p4)6;定义了一个行指针数组,数组名为p,共有4个元素,每个元素都是一个可以指向包含6个元素的int型一维数组的指针变量,即行指针变量。对于如下语句:int a46;定义的二维数组,我们知道,a+i(0i4)是行指针,它指向二维数组的第i行(包含6个元素),即指向一个包含6个元素的一维数组。因此我们可以用a,a+1,a+3来初始化

11、行指针数组p,语句如下:int (*p4)6=a, a+1, a+2, a+3;这样,行指针数组p的第i个元素pi就指向二维数组a的第i行,即行指针数组元素pi中存储的是一个行指针。根据行指针的特点可知,*pi是指向二维数组a的第i行第0列的元素指针,它指向ai0元素,因此*pi+j则指向aij,即aij与*(*pi+j)等价。例10.2 某班有4个学生,学5门课程,每个学生5门课程的成绩及总成绩已给出,要求将他们按总成绩由高到低排序后输出。定义二维数组score47来存放4个学生的成绩信息,第0列用来存放学生编号,第1至第5列分别用来存放5门课程的成绩,第6列用来存放总成绩。定义行指针数组p

12、4,并将pi赋值为score+i,即让pi指向二维数组score的第i行。如图10-5所示。图10-5 行指针数组的定义与赋值程序如下:#include void main() int score47=1, 80, 82, 95, 88, 93, 438, 2, 86, 54, 80, 95, 57, 372,3, 80, 70, 56, 88, 93, 387, 4, 95, 89, 87, 80, 96, 447;int i, j,(*p4)7;void sort(int (*p)7, int); / 声明被调用函数的原型for (i=0; i4; i+)pi=score+i; / 令行指

13、针数组元素pi指向二维数组score的第i行sort(p, 4); / 实参p是行指针数组名printf(No.tscore1tscore2tscore3tscore4tscore5ttotaln);for (i=0; i4; i+) for (j=0; j7; j+)printf(%3dt, *(*pi+j);printf(n);void sort(int (*p)7, int n) / 对行指针数组p所指向的学生成绩表排序int i, j, post;int (*t)7;for (i=0; in-1; i+) / 用选择法对学生成绩表按总成绩降序排序post=i;for (j=i+1; j

14、*(*ppost+6) / 比较两个学生总成绩的大小post=j;if (post!=i) / 交换行指针数组元素的指向t=pi; pi=ppost; ppost=t;运行结果如下:No. score1 score2 score3 score4 score5 total4 95 89 87 80 96 4471 80 82 95 88 93 4383 80 70 56 88 93 3872 86 54 80 95 57 372其中,排序函数sort实现对学生成绩表按总成绩的降序排序,排序过程中,并没有真正移动学生成绩表的存储,仅仅是通过交换指向学生成绩的行指针来实现排序,最后,按行指针数组p中

15、数组元素的顺序得到的学生成绩(即行指针数组元素所指向的学生成绩行)表就是按总成绩降序排序的。10.1.4 多级指针1指向指针的指针与指向行指针的指针例10.1中定义了指针数组book,它的每一个元素booki是一个指向字符的指针变量;数组名book也是一个指针,它是指向book0的指针。因此book是一个指向指针的指针。假设有一个指向int型变量i的指针变量p,p的值是指针,即变量i的指针&i;指针变量p本身又有指针(即&p),它是指向指针的指针;我们再定义一个指针变量b来存放指向指针的指针&p,这样指针变量b就指向了指针变量p,称指针变量b为指向指针的指针变量。如图10-6所示。图10-6

16、指向指针的指针、指针变量指向指针的指针变量的定义形式如下:类型标识符 *变量名;例如,语句:int *b;定义了一个指向指针的指针变量b。b的类型为int *,*b的类型为int *,*b的类型为int。指向行指针的指针变量的定义形式如下:类型标识符 (*变量名)指向的数组长度;例如,语句:int (*b)4;定义了一个指向行指针的指针变量b。它的值*b是一个行指针,即*b指向一个包含4个int型元素的一维数组;*b是一个指向int型存储单元的指针,即*b指向*b所指向一维数组的第0个元素;*b是一个int型数据,即*b就是*b所指向一维数组的第0个元素。例10.3 指向指针的指针变量和指向行

17、指针的指针变量。#include void main() int a34=11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34;int (*p3)4=a, a+1, a+2; / 定义行指针数组pchar *q=WAN CX, SHU W, LUO SW, LIU XP; / 定义指针数组qvoid prn1(char *, int), prn2(int (*)4, int, int); / 声明被调函数的原型prn1(q, 4); / 实参q是指向指针的指针prn2(p, 3, 4); / 实参p是指向行指针的指针void prn1(char *b,

18、int k) / 形参b是指向指针的指针变量int i; for (i=0; ik; i+)printf(%c , *b+); / 输出*b所指向字符串的第一个字符printf(n);void prn2(int (*b)4, int m, int n) / 形参b是指向行指针的指针变量int i, j;for (i=0; im; i+, b+) for (j=0; jn; j+) / 输出*b所指向一维数组的每一个元素printf(%d , *(*b+j); printf(n);执行结果如下:W S L L 11 12 13 14 21 22 23 24 31 32 33 34 2指向指针的指

19、针数组与指向行指针的指针数组如果数组中的每一个元素都是用来存储一个指向指针的指针,则该数组称为指向指针的指针数组,即每一个数组元素都是指向指针的指针变量。指向指针的指针数组的定义形式为:类型标识符 *数组名数组长度;例如,语句:int *b5;定义了一个指向指针的指针数组,数组名为b,共有5个元素,每个元素bi(即*(b+i))都是一个指向指针的指针变量,它的值*bi(即*(*(b+i))是一个指向int型存储单元的指针,因此,*bi(即*(*(b+i))是一个int型数据。指向行指针的指针数组的定义形式如下:类型标识符 (*变量名数组长度)指向的数组长度;例如,语句:int (*b5)4;定

20、义了一个指向行指针的指针数组,数组名为b,共有5个元素,每个元素bi(即*(b+i))都是一个指向行指针的指针变量,它的值*bi(即*(*(b+i))是一个指向包含4个元素的一维数组的指针,因此,*bi(即*(*(b+i))是一个指向一维数组(它是*bi所指向的一维数组)的第0个元素的指针,*bi(即*(*(b+i))是一维数组(它是*bi所指向的一维数组)的第0个元素。例10.4 指向指针的指针数组。#include void main() char *p=WAN CX, SHU W, LUO SW, LIU XP; / 定义指针数组pchar *b4; / 定义指向指针的指针数组bint

21、i;for (i=0; i4; i+)bi=p+i; / 给指向指针的指针数组元素bi赋值for (i=0; i4; i+)printf(%sn, *bi);printf(n);运行结果如下:WAN CXSHU WLUO SWLIU XP10.2 返回指针的函数10.2.1 返回指针的函数一个函数不仅可以带回一个整型值、字符值、实型值等,也可以带回一个指针型的值。这种返回指针的函数头(即函数的说明部分)的一般定义形式如下:类型标识符 *函数名(形参列表)例10.5 返回指针的函数。#include void main() int a10=60, 30, 27, 54, 59, 92, 47,

22、76, 82, 18, *max(int *), *p;p=max(a);printf(Max=%dn, *p);int *max(int *p) int i, *q=p;for (i=1; i*q) q=p+i;return q;执行结果如下:Max=92函数max的功能是查找实参传过来的一维数组a中最大值的元素,并将指向该最大值元素的指针返回给主调函数,即返回一个指向int型存储单元的指针。如图10-7所示。函数调用结束后返回92存储单元的指针图10-7 返回指针的函数注意:函数所返回的指针必须是指向尚未释放的存储单元的指针,如全局变量、主调函数定义变量所分配的存储单元,或动态存储分配函数

23、所分配的存储单元(见10.4.2小节)等。如果函数所返回的指针是指向本函数所分配的存储单元,则可能得不到正确的结果。例如,如果将例10.5中的max函数修改为如下形式,则main函数中的输出结果可能不正确,这是因为返回指针所指向的m变量在函数返回后被释放了。int *max(int *p) int i, m=*p;for (i=1; im) m=*(p+i);return &m;10.2.2 返回行指针的函数把返回指针的函数和二维数组行指针的概念结合起来使用,就可得到返回行指针的函数头(即函数的说明部分)的一般定义形式:类型标识符 (*函数名(形参列表)数组长度例10.6 二维数组score4

24、7存放了4个学生5门课程的成绩及总成绩,第0列存放学生编号,第1至5列存放5门课程的成绩,第6列存放总成绩。要求调用函数max找出总成绩最高的学生,并返回指向该学生的行指针,然后在主函数中输出该学生的成绩。程序如下:#include void main() int score47=1, 80, 82, 95, 88, 93, 438, 2, 86, 54, 80, 95, 57, 372,3, 80, 70, 56, 88, 93, 387, 4, 95, 89, 87, 80, 96, 447;int j, (*p)7;int (*max(int (*)7, int)7; / 声明被调用函数

25、的原型p=max(score, 4); / 实参score是二维数组名,即行指针printf(No.tscore1tscore2tscore3tscore4tscore5ttotaln);for (j=0; j7; j+)printf(%3dt, *(*p+j);printf(n);int (*max(int (*p)7, int n)7 / 指出总成绩最高的学生int i, (*q)7=p;for (i=1; i(*q)6) q=p+i;return q; / 返回总成绩最高的学生的行指针运行结果如下:No. score1 score2 score3 score4 score5 total

26、4 95 89 87 80 96 44710.3 函数的指针程序在编译时,每一个函数都分配了一个入口地址,这个入口地址就称为函数的指针。10.3.1 指向函数的指针变量指针变量不仅可以指向一般变量,也可以指向数组和结构体类型变量,还可以指向函数。我们可以定义一个指针变量来指向函数。指向函数的指针变量的一般定义形式如下:类型标识符 (*变量名)();例如,语句:int (*p)();定义了一个指针变量p,指针变量p可以用来指向一个返回int型值的函数。这里,*p两侧的括号不可少,(*p)代表p是一个指针变量,(*p)()则代表p是一个指向函数的指针变量。指向函数的指针变量定义后,并没有明确表示指

27、向哪一个函数。将某个函数的指针(函数名就代表该函数的指针)赋给指向函数的指针变量后,该指针变量就指向该函数,以后就可以通过该指针变量来调用该函数。通过指向函数的指针变量调用所指向函数的一般调用形式为:(*指针变量名)(实参列表);例如,有一返回int型值的函数max,则:int (*p)(); /* 定义指向函数的指针变量p */p=max; /* 使指针变量p指向函数max */z=(*p)(a, b); /* 通过指针变量p调用函数max */等价于:z=max(a, b);例10.7 用梯形法求定积分的近似值。用梯形法求定积分的近似值的公式为:其中,为等分小区间数,。以下程序调用trap

28、函数求定积分,被积函数分别是: fun1(x)=1+x+x*x,且a=0,b=2,n=2000。 fun2(x)=5+2*x+3*x*x,且a=1,b=2,n=1000。程序如下:#include #include double fun1(double x) return (1.0+x+x*x);double fun2(double x) return (5.0+2*x+3*x*x);double trap(double (*p)(double), double a, double b, double n) double t, h;int i;t=0.5*(*p)(a)+(*p)(b);h=fabs(b-a)/n;for (i=1; i=n-1; i+)t=t+(*p)(a+i*h);t=t*h;return (t);void main( ) double y1, y2, (*p1)(double), (*p2)(double);p1=fun1;p2=fun2;y1=

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

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