书签 分享 收藏 举报 版权申诉 / 53
上传文档赚钱

类型第十章-指针(大学FORTRAN程序课件).ppt

  • 上传人(卖家):三亚风情
  • 文档编号:2694236
  • 上传时间:2022-05-18
  • 格式:PPT
  • 页数:53
  • 大小:249KB
  • 【下载声明】
    1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
    2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
    3. 本页资料《第十章-指针(大学FORTRAN程序课件).ppt》由用户(三亚风情)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
    4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
    5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    第十 指针 大学 FORTRAN 程序 课件
    资源描述:

    1、第十章 指针 指针是现代程序设计语言中一个非常重要的概念,它使语言的功能大大加强。FORTRAN90以前的FORTRAN版本,没有指针这种数据类型,FORTRAN90对其作了重大改进,引入了指 针 的 概 念 。 但 是 值 得 注 意 的 是 ,FORTRAN90的指针与C语言中的指针并不相同,因为它并不代表一个变量的地址,而是代表一个变量的别名,实质上它相当于C+里的引用,本章介绍指针的概念与应用。10.1 指针的定义与使用 在前面内容中,变量的使用,都是按变量的名字即标识符直接进行的,并且每个变量的名字都是唯一的,是否可以给同一个变量一个不同的名字?FORTRAN90中的指针,正是用来给

    2、变量起别名,并且通过后面的章节的学习,我们知道指针能给编程带来诸多的方便。10.1.1 指针变量的定义格式 指针变量的定义格式为:类型说明,POINTER:指针变量名1,指针变量名2,其中:(1)类型说明可以是任何数据类型,如INTEGER、REAL等,它表示该指针所指的目标变量类型。(2)POINTER为指针定义的关键字,:为作用域符。(3)指针变量名为标识符,只要符合标示符的命名规则即可。例如INTEGER,POINTER:A1,A2此语句定义了两个指针变量A1和A2,它们都指向整型变量。 可以将类型说明与指针说明分开,即先说明变量的类型,然后指定变量为指针。例如INTEGER A1,A2

    3、POINTER A1,A2此语句同样定义了整型两个指针变量A1和A2。 10.1.2、指针变量的使用 下面通过一个具体的实例来说明指针变量的使用:例10.1指针变量示例1PROGRAM POINTER1INTEGER,POINTER:PINTEGER,TARGET: XREAD*,XP=XPRINT*,X=,XPRINT*,P=,PEND输入3,程序的输出结果为:X=3P=3此例中,先定义了一个指针变量P,然后定义了一个整型变量X,再通过P=X语句,使P指向X,这时两者实际上是同一个变量,就象一个人除了自己的名字外,还有外号一样。因此,无论输入的是什么整数,两者显示的结果一样。X和P的关系如图

    4、10.1所示X 5P 图10.1下面再看一个例子例10.2PROGRAM POINTER3 INTEGER, POINTER:P1,P2,P3,P4INTEGER,TARGET: X1,X2INTEGER X,S1,S2,S3,S4,S5READ*,X1,X2X=X1*X2P1=X1P2=X2P3=X1P4=P1S1=P1*P2S2=P3*P2S3=P1*X2S4=P3*X2S5=P4*X2PRINT*,X=,XPRINT*,S1=,S1PRINT*,S2=,S2PRINT*,S3=,S3PRINT*,S4=,S4PRINT*,S5=,S5END输入:3 4后,输出结果为:X=12S1=12S

    5、2=12S3=12S4=12S5=12在该例中,定义了四个指针变量:P1,P2,P3,P4,通过P1=X1,使P1指向X1,P2=X2使P2指向X2,再通过P3=X1和P4=P1,使P3和P4都指向X1,因此,X、S1、S2、S3、S4、S5计算结果一样,实际上都是X1+X2。下面用图表示X1、X2、P1、P2、P3、P4的关系如图10.2、10.3所示:X1(1) 指针变量赋值格式为:指针变量=目标变量或者另一指针变量。(2) 多个指针变量可以指向同一目标变量,但是,一个指针变量只能指向一个目标变量,不能同时指向多个目标变量。(3) 指针变量与目标变量的类型应当严格一致,不存在所谓的兼容情况

    6、,即,整型指针变量所指的只能是整型变量,而不能是实型变量等。(4) 指针变量的本质是所指变量的别名,两者在编译时会当作同一变量,指针变量的引用实际上是对目标变量的引用。 (5) 在程序中,指针变量通常有以下三种状态: 未定义状态,在程序开始时,所有的指针都处于这种状态。 空状态,此时指针还没有作为任何对象的别名。在程序中,有时为了方便起见,可以让指针指向一个空对象。其语句为:NULLIFY(指针变量名)。 关联状态,此时,指针已经作为其他对象的别名。值得注意的是只有在第三种状态时,指针才能参与运算,否则,或者编译出错,或者非法操作。10.2 动态变量 前面已介绍过,变量的本质是一个内存单元,该

    7、单元一般是在变量定义时,就已经分配的,以后在程序运行期间不再改变,但是通过指针,可以先得到变量名,然后再利用ALLOCATE(P)函数可以动态分配其空间,其中P为指针变量。下面通过一个具体实例,来了解其使用方法。 例10.3PROGRAM POINTER3 INTEGER,POINTER:PALLOCATE(P)P=4PRINT*,P=,PEND输出结果为:P=4 在该例中,先定义了一个指针变量P,然后利用ALLOCATE(P)函数,为P分配空间,再给P赋值。必须注意的是:如果去掉ALLOCATE(P)语句,则该程序运行时会出现错误,因为指针在未指定目标时是虚的,不能引用。一般而言,ALLOC

    8、ATE函数总是与DEALLOCATE函数配套使用,因为用动态分配函数为指针分配存储单元时,容易产生指针悬挂问题。所谓指针悬挂问题是指:当一个对象被释放,而释放时没有直接涉及作为其别名的指针时,就产生指针悬挂,这时,指针所占据的内存单元始终得不到释放,使用DEALLOCATE函数就可释放存储单元。注意,对于普通变量,由于其内存空间自动回收,不存在上述问题。 例10.4,ALLOCATE和DEALLOCATE函数的用法,程序如下: PROGRAM POINTER4 INTEGER,POINTER:P1,P2INTEGER SALLOCATE(P1,P2)READ*,P1,P2S=P1+P2DEAL

    9、LOCATE(P1,P2)PRINT*,S=,SEND输入5 6输出S=11 该程序中,先定义了两个指针变量P1、P2,然后用ALLOCATE函数为其分配空间,再通过键盘输入其值,运算完毕,用DEALLOCATE函数,释放其空间。必须注意的是:DELLOCATE函数所释放的空间,一定得是不再使用的动态空间,空间一旦被释放,就不得再使用,否则将产生非法操作,如上面程序中,如果将DEALLOCATE(P1,P2)语句提前,就会产生非法操作。注意,即使用DEALLOCATE(P)函数,释放P所指的空间,也可能产生悬挂指针问题,下面我们看一个可能产生悬挂指针的例子。 REAL, POINTER : P

    10、1, P2ALLOCATE( P1 )P1 = 13P2 = P1这时,P1,P2指向同一个存储单元,如果程序中在P1使用完后,用DEALLOCATE(P1)语句,这时,P2指针就被悬挂起来。注意,ALLOCATE和DEALLOCATE还有可选用说明符STAT:ALLOCATE(P,STAT=IERR)DEALLOCATE(P,STAT=IERR)其中IERR用于标识内存分配、解除是否成功,成功则IERR的值为0。 10.3 指针与数组指针与数组 利用指针来指向一个数组,能动态地分配数组空间,给编程带来极大的方便,因为FORTRAN语言的特点是,如果要使用数组,则必须在可执行语句之前先定义它,

    11、而数组普通定义的方法是首先必须指定数组的维界,确定数组存储空间的大小,但在编写程序时,开始往往难以确定所用数组的大小,显然,所定义的数组空间的大小不能小于所需的空间,解决的办法是将数组定义得足够大,但这样浪费了内存空间,而通过动态定义,可以根据当时使用空间的大小来生成空间,使问题得到很好的解决。下面讨论指针与数组关系的建立、动态空间的生成等。10.3.1 10.3.1 指针数组的定义指针数组的定义 指针数组定义格式为:类型说明,DIMENSION(: :),POINTER:指针名其中:类型说明可以为各种数据类型,如INTEGER、REAL等;DIMENSION(: :)是数组的动态说明标识,即

    12、不指定数组下标界限,“:”个数=数组维数。POINTER为指针说明标识。例如REAL, DIMENSION(:), POINTER : XALLOCATE(X(20) 第一个语句声明了一个可以指向一维整型数组的指针X,第二个语句为该数组分配了20个单位的存储空间。下面看一个例子例10.5 输入任意两个数,将它们及四则运算结果存储起来后,输出。分析:此例中,可以利用指针,定义一个动态数组X,用来存放输入的数据和计算的结果,该数组的空间大小可以根据要存储的数据个数动态分配,程序如下: REAL,DIMENSION(:),POINTER:XREAD*,A,BC=A+BD=A-BE=A*BIF(B.N

    13、E.0)THENF=A/BELSEF=0ENDIFALLOCATE(X(6)X(1)=AX(2)=BX(3)=CX(4)=DX(5)=EX(6)=FWRITE(*,100)X 100FORMAT(1X,3F8.2)DEALLOCATE(X)END输入3 6,输出3.006.009.00-3.0018.000.5010.4 指针与链表指针与链表 指针用途之一是使得数据在计算机中可以按链接方式存储,而链接存储中,最简单是链表。下面介绍关于链表的一些基本知识。顺序存储和链接存储是数据的两种最基本的存储结构。在顺序存储中,每个存储结点只含有存储元素本身的信息,元素之间的逻辑关系是通过数组下标位置简单计

    14、算出来的。如在顺序表中,若一个元素存储在对应的数组中的下标位置为I,则它的前一个元素在对应的数组中的下标是I-1,它的后一个元素是数组中下标为I+1的元素。顺序存储最大的缺点是不利于数据的动态变化,如向顺序表中插入或删除一个元素时,需要大量移动数据,处理效率很低。在链式存储中,每一个结点除了存储自己的信息以外,还保留下一个值,用来访问下一个变量,这个值称为指针,下面介绍如何使用链表。 10.4.1 结点的定义结点的定义 结点是存放数据的基本单位,最简单的结点是普通数组的元素,如若有以下定义:INTEGER A(10) 则象A(1) 、A(2)、 A(3)、 A(4) 等,可以看作结点。复杂的结

    15、点包含多种类型的数据,一般定义为一个结构体,下面定义一个链表结点的结构体: TYPE NODEINTEGER VALUETYPE (NODE), POINTER : NEXTEND TYPE NODE该结点包含两项,一项是数据本身,即INTEGER VALUE,另外一项是一个指向下一个结点的指针NEXT,通过TYPE (NODE), POINTER : NEXT语句定义,该结点可以用图10.3表示: TYPE NODEINTEGER VALUETYPE (NODE), POINTER : NEXTEND TYPE NODE该结点包含两项,一项是数据本身,即INTEGER VALUE,另外一项是

    16、一个指向下一个结点的指针NEXT,通过TYPE (NODE), POINTER : NEXT语句定义,该结点可以用图10.3表示: VALUE 图10.3NEXT下面再看一个结构体定义的例子。TYPE STUDENTNODECHARACTER (15)NAMEINTEGER NUMLOGICAL SEXCHARACTER (30)ADDRESST Y P E ( S T U D E N T N O D E ) ,POINTER:NEXTEND TYPE图10.4 结点示意图结点结构体表示如图10.4:10.4.2 链表的基本操作链表的基本操作包括建表、插入、删除、查找、更新、遍历等,这里介绍建

    17、表、遍历、插入、删除等操作,其余操作将在下一节综合实例里介绍。1. 链表的建立例10.6 建立一个链表,并输出建表后的结果。为了便于理解,假设链表结点仅包含一个数据项和一个指针项。程序如下: TYPE NODEINTEGER VALUETYPE (NODE), POINTER : NEXTEND TYPE NODE!链表的建立,规定以0作为链表建立结束标志。TYPE (NODE), POINTER : CURRENT, LINTEGER NUMREAD*,NUMNULLIFY( L )ALLOCATE( CURRENT )CURRENT % VALUE = NUML = CURRENTDO W

    18、HILE (NUM /= 0) READ*, NUM IF (NUM /= 0) THEN ALLOCATE( CURRENT ) CURRENT % VALUE = NUM CURRENT % NEXT = L L = CURRENT END IF END DO !链表的输出过程。CURRENT = LPRINT*, CURRENT % VALUECURRENT = CURRENT % NEXTDO WHILE (ASSOCIATED(CURRENT) PRINT *, CURRENT % VALUE CURRENT = CURRENT % NEXT NEXT NODE END DO END

    19、输入:1 2 3 4 5输出:54 3 2 1 必须注意的是:链表有一个表头和一个表尾,由于FORTRAN语言中指针实际上就是一个别名,不同于C语言中的指针(C中的指针代表内存地址),因此没有明确的空指针的概念,链表的访问方式只能从最后一个结点开始,到第一个结点,通过检查链表是否再被连接作为结束标识,例10.6所建链表过程如图10.5所识。例10.7 建立有关链表的的模板函数,其中包含链表的删除、插入、输出等函数,程序如下:!模板函数的说明MODULE MODLINK IMPLICIT NONE!结点定义PRIVATE NODETYPE NODE INTEGER VALUE TYPE (NOD

    20、E), POINTER : NEXTEND TYPE NODE !定义链表头指针TYPE LIST PRIVATETYPE (NODE), POINTER : END END TYPE LIST !模板函数所包含的内容CONTAINS !删除函数DISPOSE( L ),用于清空链表。SUBROUTINE DISPOSE( L )TYPE (NODE), POINTER : CURRENTTYPE (LIST) LCURRENT = L % END DO WHILE (ASSOCIATED(L % END)L % END = CURRENT % NEXT PRINT*, CURRENT % V

    21、ALUE, IS ABOUT TO GODEALLOCATE( CURRENT )CURRENT = L % END END DOEND SUBROUTINE DISPOSE!插入函数INSERT,通过插入结点建立链表SUBROUTINE INSERT( L, NUM ) TYPE (NODE), POINTER : CURRENT TYPE (LIST) LINTEGER NUMALLOCATE( CURRENT ) CURRENT % VALUE = NUM CURRENT % NEXT = L % END L % END = CURRENT END SUBROUTINE INSERT !

    22、遍历函数PRINTLIST,用来访问链表各结点,并输出结点的值SUBROUTINE PRINTLIST( L )TYPE (NODE), POINTER : CURRENT TYPE (LIST) LPRINT*, FROM THE END: CURRENT = L % END ! ALIAS OF LAST NODEDO WHILE (ASSOCIATED(CURRENT) PRINT *, CURRENT % VALUE CURRENT = CURRENT % NEXT END DO END SUBROUTINE PRINTLIST !初始化链表,使表头指针空SUBROUTINE SETU

    23、P( L )TYPE (LIST) LNULLIFY( L % END ) END SUBROUTINE SETUP END MODULE MODLINK!主函数部分,根据要求调用前面的函数。PROGRAM TESTLISTUSE MODLINK ! LINKED LIST IMPLEMENTATIONIMPLICIT NONETYPE (LIST) LINTEGER : NUM = 1 CALL SETUP( L )DO WHILE (NUM /= 0) READ*, NUM IF (NUM /= 0) THEN CALL INSERT( L, NUM ) END IF END DO CAL

    24、L PRINTLIST( L )CALL DISPOSE( L ) END PROGRAM TESTLIST输入123450输出543215将被删除4将被删除3将被删除2将被删除1将被删除。 10.5 综合实例综合实例 用链表完成学生情况的管理,已知学生包含姓名,学号,和一门成绩等,其中学号作为关键字。完成链表的建立,和按关键字的排序,插入,查找,删除等操作。1 定义结点定义带指针的存放学生记录的结点如下:TYPE NODECHARACTER(15)NAME INTEGER MARK REAL GRADETYPE (NODE), POINTER : NEXTEND TYPE NODE 2 定义

    25、链表的头指针:TYPE LIST PRIVATETYPE (NODE), POINTER : END END TYPE LIST必须注意,放在模板函数中的链表必须为PRIVATE类型。3 链表头指针的初始化SUBROUTINE SETUP( L )TYPE (LIST) LNULLIFY( L % END ) ! LIST IS EMPTY AT FIRSTEND SUBROUTINE SETUP初始化就是将头指针清空,其主要目的是为了在链表的逆序访问中知道链表结点是否访问完毕。4 链表建立建立方式用后插方式,即不断在表头结点后面加入新结点。SUBROUTINE INSERT( L, NAME

    26、1,MARK1,GRADE1) TYPE (NODE), POINTER : CURRENT TYPE (LIST) LCHARACTER(15)NAME1INTEGER MARK1REAL GRADE1ALLOCATE(CURRENT)!为CURRENT指针分配空间和数据,生成结点。CURRENT%NAME=NAME1 CURRENT%MARK=MARK1CURRENT%GRADE=GRADE1CURRENT%NEXT =L%END !将CURRENT指针生成的结点连接到链表上。L%END = CURRENT !链表末尾指针后移,为连接新结点做准备。END SUBROUTINE INSERT

    27、5 链表删除删除过程为:先定义指针保留待删指针及相关的数据,然后删除待删指针,再输出删除的数据并移动指针保留指针,为删除下一结点作准备。SUBROUTINE DISPOSE( L )TYPE (NODE), POINTER : CURRENTTYPE (LIST) LCURRENT = L % END !从最后一个结点开始删除,用CURRENT保留待删指针即L链表的END指针。DO WHILE (ASSOCIATED(L % END)!注意循环进行条件是链表继续相连,通过ASSOCIATED函数来判断。 L % END = CURRENT % NEXT ! END指针前移。PRINT*, CU

    28、RRENT % NAME! 输出相关的数据。PRINT*, CURRENT % MARKPRINT*, CURRENT % GRADEDEALLOCATE( CURRENT )! 删除CURRENT指针,即删除结点。CURRENT = L % END !CURRENT 指针保留下一个待删结点的指针。END DOEND SUBROUTINE DISPOSE6 数据记录的查找查找是以一个关键字为基础进行的,这里用MARK作关键字进行查找,程序如下SUBROUTINE FIND(L,KEY)TYPE (NODE), POINTER : CURRENT TYPE (LIST)LINTEGER KEYP

    29、RINT*, 请输入待查找的关键字KEYREAD*,KEY CURRENT = L % END ! 从最后一个结点开始。DO WHILE (ASSOCIATED(CURRENT%NEXT)!注意循环只能进行到链表头的前一个结点,否则将产生非法操作。IF(CURRENT%MARK.EQ.KEY)THEN! 一旦找到记录,则将结果输出,并退出循环。PRINT*,与,KEY,相对应的记录如下:PRINT *,CURRENT %NAME,CURRENT %MARK,CURRENT %GRADEGOTO 100ELSECURRENT = CURRENT % NEXT ! 查找下一个记录。ENDIFEND

    30、 DOPRINT*,没有该记录!循环结束还没有找到该记录的话,说明该记录不存在。100 CONTINUEEND SUBROUTINE FIND 7 数据更新数据更新是根据给定的关键字查找到相应的记录后,再将相关项更新。SUBROUTINE UPDATA(L,KEY)TYPE (NODE), POINTER : CURRENT TYPE (LIST)LCHARACTER(15)NEWNAMEINTEGER KEY,NEWGRADE PRINT*, 请输入待更新项的关键字KEYREAD*,KEYPRINT*, 请输入待更新的其它项READ*,NEWNAME,NEWGRADE CURRENT = L

    31、 % END ! 从链表末尾开始DO WHILE (ASSOCIATED(CURRENT%NEXT)IF(CURRENT%MARK.EQ.KEY)THENCURRENT %NAME=NEWNAMECURRENT %GRADE=NEWGRADEGOTO 100ELSECURRENT = CURRENT % NEXT !查找下一个结点。ENDIFEND DOPRINT*,该项不存在,无法更新100 CONTINUEEND SUBROUTINE UPDATA8 链表输出程序如下:SUBROUTINE PRINTLIST( L )TYPE (NODE), POINTER : CURRENT TYPE (LIST)LPRINT*, FROM THE END: CURRENT = L % END DO WHILE (ASSOCIATED(CURRENT) PRINT *,CURRENT %NAME,CURRENT %MARK,CURRENT %GRADECURRENT = CURRENT % NEXT END DO

    展开阅读全文
    提示  163文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:第十章-指针(大学FORTRAN程序课件).ppt
    链接地址:https://www.163wenku.com/p-2694236.html

    Copyright@ 2017-2037 Www.163WenKu.Com  网站版权所有  |  资源地图   
    IPC备案号:蜀ICP备2021032737号  | 川公网安备 51099002000191号


    侵权投诉QQ:3464097650  资料上传QQ:3464097650
       


    【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。

    163文库