资源预览内容
第1页 / 共38页
第2页 / 共38页
第3页 / 共38页
第4页 / 共38页
第5页 / 共38页
第6页 / 共38页
第7页 / 共38页
第8页 / 共38页
第9页 / 共38页
第10页 / 共38页
亲,该文档总共38页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
10 指针与递归10.1 指针的概念 10.2 指针的使用 10.3 指针数组 10.4 链表 10.5 递归及其应用10.1 指针的概念 指针变量的定义格式: 类型,Pointer: 变量名列表 或者分两步定义: 类型 : 变量名列表 Pointer 变量名列表指针变量的类型与它的目标变量的类型 必须一致。指针变量所指向的变量称为目标变量,简 称为目标。对目标变量的定义必须用target 属性:类型, target: 变量名列表10.1 指针的 概念指针赋值语句: 指针变量=目标变量 赋值号=读作“指向”,注意它的写法。 同类型的指针变量可相互赋值 指针变量=指针变量指针变量通过指针赋值语句指向目标变量 之后, 使用目标变量和使用它的指针是等同 的。这两者之间的暂时等同关系直到用指 针赋值语句使指针变量指向另外的目标变 量为止。10.1 指针的概念 例:Real,pointer :p1,p2 !p1,p2可指向实 型目标变量。Real,target:x,y !实型目标变量 P1=x;p2=y !指针赋值语句 X=-0.618 ! P1=-0.618 P2=1.414 ! Y=1.414 例:Real,Dimension(:),pointer :p !p可 指向有target属性的一维实型数组(包括二 维数组的一行或一列)。Real,target:a(5,6) !实型目标数组 P=A(2,:) !指针赋值语句 p=1 ! 赋值语句,使A数组第2行元素全为1例:Real,pointer :p1,p2Real,target:r=13P1=rP2=p1Prinr*,p1,p2,rendReal,pointer :p1,p2Real,target:r1=13Real,target:r2=15Print*,r1,r2P1=r1;p2=r2Print*,p1,p2P1=p2Print*,p1,p2,r1,r2r2=2*r2P2=p1Print*,p1,p2,r1,r2end说明:(1)指针变量通过指针赋值语句指向目标变 量之后,便成为所指向目标的别名。(2)对于一个指针变量的访问,实际上就是 对其目标变量的访问。(3)可以有多个指针同时指向同一个目标变 量,如:P1=R,P2=R 。但不可能一个指 针同时指向多个目标变量。(4)指针赋值可以改变当前的别名。例如:p2=p1使p2指向p1所指向的目标。10.2 指针的使用指针处于三种状态之一: 未定义:程序刚开始时所有指针都未定义 空指针:已定义但没有指向任何目标 关联:指针已定义并指向某一目标NULLIFY语句的作用是使指针变量处于 空状态。其格式为: NULLIFY(p) P是指针变量10.2.1 指针的状态10.2.2 NULLIFY语句10.2 指针的使用例:Real,Pointer:p1,p2 Real,Target:a P1=a;p2=a !p1,p2都指向a NULLIFY(p1) !p1为空, p2指向a P2=p1 !p1与p2都为空指针用Allocate分配一块内存,并使指针变量指向它, 指针变量就成了这块内存的别名。这就是动态 变量。 Allocate语句的格式: Allocate(p,Stat=整型变量名) P必须已定义,整型变量表明分配是否成功,分 配成功,整型变量被赋值0,否则赋非0值。10.2.3 动态变量10.2 指针的使用 例:Real,Pointer:p Allocate(p) !给指针p分配内存用DeAllocate语句可以释放已分配给某指针 变量的内存,并使该指针变量置空。其格式 为:DeAllocate(p,Stat=整型变量名) 例:Real,Pointer:p Allocate(p) !给指针p分配内存 P=13;print *,p DeAllocate(p) !释放指针p的内存 End10.2 指针的使 用例:Real,Pointer:p1(:) Real,Allocatable,Target:p2(:,:) Allocate(p1(1:8),stat=I) !给指针p1分配内存 If(I=0) print *,P1分配成功 P1=2.5; print “(1x,8f8.1)“, p1 Allocate(p2(1:8,1:3),stat=I) !给数组p2分配内存 If(I=0) print *, “P2分配成功“ P2=1.5;p2(1:8:2,2)=6.8;write(*,“(1x,8f8.1)“)p2 P1=p2(2:7,2); print “(/1x,8f8.1)“, p1 Nullify(p1) Deallocate(p2,stat=i) If(I=0) write(*,“(/1x,A)“) “P2释放成功“ End例:Implicit noneType studentinteger:numreal:scoretype(student),pointer:nextEnd Type studentType(student),pointer:p1,p1Allocate(p1)Allocate(p2)Read*,p1%num,p1%scoreRead*,p2%num,p2%scoreNullify(p1%next); Nullify(p2%next)Print*, p1%num,p1%scorePrint*, p2%num,p2%scoreDeallocate(p1)Deallocate(p2)end10.2 指针的使用逻辑型固有函数ASSOCIATED检查一指针是 否指向一个目标或是否为另一个对象的别名。其 格式为:ASSOCIATED(p1,p2) 待检查的指针p1必须已定义;可选参数p2如果 是目标变量,则检查p1是否指向它,p2若是指针, 则检查p1与p2是否指向同一目标或同时为空指 针。例:Real,Pointer:p,q ; NULLify(q); !Q是空指针 If(ASSOCIATED(p,q) then Print*,”p是空指针” Else Print*,”p不是空指针”10.2.4 ASSOCIATED固有函数End ifend如果p1,p2指向同一数组的不同部分,它们 被认为是未结合的。Implicit noneReal,target,dimension(4):a=(/1,2,3,4/)Real,pointer,dimension(:):p,qP=a(1:3)Q=a(2:4)Print*,associated(p,q)end10.2 指针的使用没有指向任何对象的指针就是悬空指针。 刚刚定义的指针就是悬空的。用DeAllocate 语句间接释放的指针很可能是悬空的。悬空指针有不定值,引用悬空指针的结果是随 机的,表现为程序运行不稳定或死机。不经过内存释放的步骤而将动态变量的指针 直接置空或指向其它目标,就会使该变量所占 的内存不可访问。这会造成内存浪费。10.2.5 悬空指针与无法访问的内存10.3 指针数组 指针数组是由指针组成的数组。容易与之混 淆的概念是数组指针:指向数组的一个指针。 Real,Dimension(:),Pointer:A !A是数组指针 Dimension B(10),C(8,5) A=B !A指向一维数组B A=C(:,4) !A指向二维数组C的第4列数组指针也可以是动态变量 Real,Dimension(:),Pointer:A !A是数组指针 Allocate(A(50) !给指针A分配内存 A=10;print *,A DeAllocate(A) !释放指针A的内存 End10.3 指针数组 当数组指针是动态变量时,它所分配到的内 存区被当作一个数组使用,但是,该数组是没有 名字的,数组指针的名字就作为它的别名。下面的例子说明A不是一个指针数组: Dimension(:),Pointer:A !A是数组指针 Real,target:b=2 Allocate(A(50) !给指针A分配内存 A(1)=B !错误,A(1)不是指针 A(2)=64; print *,A(2) DeAllocate(A) !释放指针A的内存 End10.3 指针数组 指针数组只能用间接方法实现。 例:定义一个具有5个元素的指针数组。 TYPE real_pointerreal,pointer:p END type real_pointer Real,target:a,b,c,d,e,f,g,h,x,y TYPE(real_pointer) R(5) Data a,b,c,d,e,f,g,h,x,y/1,2,3,4,5,6,7,8,9,10/ R(1)%p=b;r(2)%p=d;r(3)%p=f r(4)%p=h;r(5)%p=y Print *,(R(I)%p,I=1,5),a,c,e,g,x END10.3 指针数组 事实上,上例中并没有一个指针数组,因为数 组的类型是派生类型real_pointer,而不是指向 实型目标的指针。指向实型目标的指针p是数 组元素的一个成员,而不是数组元素本身。 使用数组的最大好处是可以进行下标运算, 上例中确实存在5个指向实型目标的指针,也确 实可以象使用数组一样通过使用R数组的下标 变量R(I)的成员p来实现下标运算。因此上说 它间接地实现了指针数组。在FORTRAN 90中,严格地由指针组成的指 针数组是不能实现的。IMPLICIT NONEINTEGER:ITYPE ROWREAL ,DIMENSION(:),POINTER:REND TYPE ROWINTEGER,PARAMETER:N=6TYPE(ROW),DIMENSION(N):S,TDO I=1,NALLOCATE(T(I)%R(1:I)T(I)%R(1:I)=IEND DOS=T !相当于 s(I)%r=t(I)%rDo I=1,nPrint*,s(I)%r(1:I)End doDo I=1,ns(I)%r(1:I)=2*iEnd doDo I=1,nPrint*,t(I)%r(1:I)End doend1.02.0 2.03.0 3.0 3.04.0 4.0 4.0 4.05.0 5.0 5.0 5.0 5.06.0 6.0 6.0 6.0 6.0 6.0 2.04.0 4.06.0 6.0 6.08.0 8.0 8.0 8.010.0 10.0 10.0 10.0 10.012.0 12.0 12.0 12.0 12.0 12.0 10.4 链表n链表概念n链表的创建n链表的插入n链表的删除n链表的输出n链表举例10.4.1 链表概念链表是一个节点的序列,其中每个节点被连接 到它前面的节点上。从上面链表可知,每个节点有二个域,第一个是数 据域,第二个是指针域。链表的第一个节点称为表 头,最后一个节点称为表尾。指向表头的指针称为 头指针,最后一个节点的指针域为空指针。没有任 何节点的链表称为空链表。空链表的头指针为空。为了表示链表,必须先定义一个派生类型来表 表示节点的结构。例如整型数值链表中节点的 类型定义为:Type nodeinteger :valuetype(node),pointer:nextEnd Type node 表头节点的指针可用下述方法建立:Type listtype(node),pointer:headEnd Type listType(list):L则L%head为链表表头节点的指针。10.4.2 链表的创建 用一
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号