




已阅读5页,还剩91页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第七讲子程序 7 1语句函数 7 5可调数组 7 2函数子程序 7 3子例行子程序 7 4虚实结合 7 6程序举例 7 1语句函数 一 语句函数的概念二 语句函数的定义三 语句函数的引用 一 语句函数的概念 引例 计算W 0 2P X 0 3P Y 0 5P Z 其中P T 0 812T3 1 256T2 3 378T 0 689 WRITE 请输入X Y Z的值 READ X Y ZP1 0 812 X 3 1 256 X 2 3 378 X 0 689P2 0 812 Y 3 1 256 Y 2 3 378 Y 0 689P3 0 812 Z 3 1 256 Z 2 3 378 Z 0 689W 0 2 P1 0 3 P2 0 5 P3WRITE WEND 上例三次使用同一公式 下面利用FORTRAN提供的语句函数来简化之 程序可改写如下 P T 0 812 T 3 1 256 T 2 3 378 T 0 689WRITE 请输入X Y Z的值 READ X Y ZP1 P X P2 P Y P3 P Z W 0 2 P1 0 3 P2 0 5 P3WRITE W WEND 规定 语句函数是在使用的程序段内部用一个语句定义的函数 必须在程序段的开头定义 且只能在该段的内部使用 在程序中有时可能在好几处需要进行同样的某种表达式计算 而这种计算又不是某个内部函数所能完成的 这时 程序设计者可以自已来定义一个语句函数 通过引用语句函数来实现这种特殊运算 二 语句函数的定义 语句函数定义的形式 f name x x e 使用规定 1 语句函数定义语句必须位于该程序段的说明语句之后 第一个可执行语句之前 它是非执行语句 2 语句函数名不能与本程序单元中的任何其它名字同名 f name的类型可以隐含 也可以显式说明 f name与e的关系遵循语句的赋值规则 3 形参X只能是变量 用于表示函数中自变量的个数 类型和顺序 与本程序段中的其它名字无关 x1 x2 xn本身是没有值的 只有在函数引用时用实在自变量 实参 代替虚参情况下 才能得到函数值 虚参在形式上与普通变量名相同 虚参之间不能同名 使用规定 4 e是含有x1 x2 xn的表达式 在这个表达式中 除必须包含有关虚参外 还可以包含常量 变量 外部和内部函数和已定义过的语句函数 5 语句函数只能在定义它的程序段使用 三 语句函数的引用 语句函数的引用就是对语句函数定义的使用 它和内部函数一样 总是在表达式中作为一个运算分量或单独作为一个表达式出现 它的一般引用形式为 f name a1 a2 注 实参的个数 类型及排列顺序必须与相应的形参一致 三 语句函数的引用 REALA B CSUM A B C A B B C 3DATAA B C 1 0 2 0 3 0 Y1 SUM 0 5 0 7 0 8 Y2 SUM 2 A B C Y3 SUM C B A Z Y1 Y2 Y3WRITE Y1 Y2 Y3 ZEND Y1 0 5 0 72 0 83 Y2 2 0 2 02 3 03 Y1 3 0 2 02 1 03 语句函数的引用过程 当程序执行到一个语句函数的引用时 要经过下列几个过程 当实元为表达式时 先求出表达式的值 然后控制转到语句函数定义语句去执行 实元和对应的虚元进行结合 即实元的值传给虚元 称为虚实结合过程 求表达式e的值 这一过程是由计算机系统来完成的 用户可不必担心 根据语句函数名的类型和表达式e求值结果 按赋值规则得到函数引用的值由函数名带回 并控制返回到原表达式函数引用处 继续计算表达式值 语句函数的引用过程 三 语句函数的引用 DATAA 2 0 F X X 1B F F F A WRITE BEND F F F 2 0 F F 3 0 F 4 0 例1 二分法 1 基本思路 把区间 x1 x2 二等分 找到中点x求出f x 值 然后判断f x 和f x1 是否同号 如同号则说明根在 x x2 区间 否则 根在 x x1 区间 依次方法对有根区间再折半 直到满足条件为止 例 用二分法求f x x3 6x 1 0在x 2附近的一个实根区间为x1 0 x2 5 x y x1 x2 x f x1 f x f x2 0 F X X 3 6 0 X 1 0100READ X1 X2FX1 F X1 FX2 F X2 IF FX1 FX2 GT 0 0 GOTO10010X X1 X2 2 0FX F X IF SIGN FX FX1 EQ FX THENX1 XFX1 FXENDIFIF SIGN FX FX2 EQ FX THENX2 XFX2 FXENDIFIF ABS X1 X2 GT 1E 5 AND ABS FX GT 1E 6 GOTO10IF FX GT 1E 6 X X1 X2 2 0WRITE XEND SIGN x1 x2 是符号传递函数 函数值取x2的的符号 取x1的绝对值 算法 弦截法的基本思路与 二分法 相似 它是取f x1 与f x2 连线与x轴的交点x 从 x1 x 与 x x2 两个区间中舍去一个 舍取的方法为 1 如果f x 与f x1 异号 则用x作为新的x2 这就舍去了原来的 x x2 区间 2 如果f x 与f x1 同号 则用x作为新的x1 这就舍去了原来的 x1 x 区间 如果f x1 与f x2 异号 则它们之间的连线必然交x轴于x点有x x2 x2 x1 f x2 f x2 f x1 3 再根据新的x1 x2 找到与x轴的交点x 重复上述步骤 例2 用语句函数采用弦截法求X3 2X2 7X 4 0的根 LOGICALSF X X 3 2 0 X 2 7 0 X 4 0S A B SIGN A B EQ A10READ X1 X2F1 F X1 F2 F X2 IF S F1 F2 GOTO10F0 1 020IF ABS X1 X2 GT 1E 5 AND ABS F0 GT 1E 6 THENX X2 X2 X1 F2 F1 F2F0 F X IF S F0 F1 THENX1 XF1 F0ENDIF IF S F0 F2 THENX2 XF2 F0ENDIFGOTO20ENDIFIF ABS F0 GT 1E 6 X X1 X2 2 0WRITE XEND 语句函数小结 语句函数必须先定义 后引用 且语句函数只可在包含该语句函数定义的程序单位中引用 即不能引用其他程序单位所定义的语句函数 语句函数定义语句是非执行语句 它应该放在所有可执行语句之前和有关的类型说明语句之后 语句函数定义中的函数名和虚元是具有类型的 可以用类型说明语句说明其类型或按隐含约定确定其类型 如 INTEGERG X Y G X Y N X X N Y 以上语句说明G函数是整型函数 即函数值为整型 且说明虚元X Y为整型 隐含约定N为整型 语句函数小结 在语句函数定义的语句中 也可出现其他的语句函数引用 但被引用的语句函和须在它前面已定义 不允许引用自身或在它后面定义的语句函数 例 S A B C A B C 2 0 PP A B C SQRT S A B C A PP函数引用了它前面所定义的S函数 语句函数小结 引用语句函数时 给定的实元必须和对应的虚元个数相等 类型一致 位置相符 在进行虚实结合时 虚元与实元不是以名字相同传值 而是按位置类型一一传值 语句函数小结 例 F X X X X 1 0 X 3 0 Y X 3 0 2 0 Z F 1 0 F 2 0 F 3 0 T F X 在同一程序单位中不允许变量名与函数名同名 但允许变量与虚元同名 程序第一行的X是语句函数的虚拟参数 第二行的X是变量名 它们彼此独立 无任何关系 第三行计算出Y的值等于2 0 第四行引用语句函数 分别将1 0 2 0 3 0代替语句函数定义语句中右边表达式的X 计算出F 1 0 F 2 0 F 3 0 第五行F x 中的X是变量名 其值为3 0 此时F X 相当于F 3 0 7 2函数子程序 外部函数 语句函数只能用一个语句定义 而且只能在定义它的程序段中使用 分析 函数f X 是用两个表达式定义的 不能用简单的语句函数来表示 怎么办 FORTRAN提供了一种方法 就是把函数的计算部份从程序中独立出来 并按一定的格式编成一个单独的子程序段 称为外部函数或函数子程序 FUNCTIONF X IF X GE 0 F 2 X 1IF X LT 0 F 3 X 1END 引用 返回 一 引例 一个FORTRAN程序可以由一个以上程序单位组成 这程序单位分别称为主程序和子程序 每个程序单位都可由FORTRAN编译程序单独进行编译 进行语法检查 生成目标代码 最后再连接装配在一起 成为一个可执行程序 图1是一个可执行FORTRAN程序的结构示意图 其中每个方框代表一个单独的程序单位 可以看到 一个FORTRAN程序必须有一个主程序 而且只能有一个主程序 一个程序中 可以根据需要包含任意数量的子程序 子程序可以被主程序调用 也可以被其它子程序调用 但不能发生直接或间接地自已调用自己 如图2中所示的调用关系是错误的 主程序 子程序C 子程序B 子程序A 子程序D 子程序E 子程序D 子程序E 子程序G 子程序F 子程序F 图1 主程序 子程序C 子程序A 子程序B 子程序C 子程序B 图2 FORTRAN子程序 函数子程序 外部函数 子例行子程序 数据块子程序 说明子程序 FUNCTION函数名 a1 a2 an 说明语句 可执行语句 END SUBROUTINE子例行程序名 a1 a2 an 说明语句 可执行语句 END BLOCKDATA名字 说明语句 END a 函数子程序结构 b 子例行程序结构 c 数据块子程序结构 子程序是一个独立的程序单位 其主要特点 1 形式独立 每种类型的子程序均以子程序单位语句开始 以END结束 2 符号独立 子程序单位中使用的语句标号 变量名 数组名等是独立的 即使与其他程序单位的符号相同 无需特殊声明 也彼此无关 3 位置独立 子程序可以放在主程序之前或之后都无所谓 执行时总是从主程序开始执行 4 编译独立 如果每个子程序是以一个文件存贮的 则可以单独进行编译 这样使得便于编写 便于维护 并能实现软件共享 二 外部函数的定义 函数子程序通常称为外部函数 它也是根据程序设计者的需要由自己定义的函数 和语句函数不同的是 函数子程序是一个由若干语句组成的独立的程序单位 当某些函数的值不可能用一条语句来求得时 就可借助函数子程序来定义一个函数 二 外部函数的定义 一般形式 类型说明FUNCTION函数名 虚参表 函数子程序体END FUNCTION函数名 虚参表 类型说明函数名函数子程序体END 说明 1 FUNCTION语句是函数子程序的第一条语句 标志着该函数子程序的开始 类型说明function函数名 虚参表 六种类型说明函数名的类型 关键字 该函数子程序的名字 虚元表 例 functionrdh n h 实型函数Integerfunctionrdh n h 整型函数 注意 1 函数名的命名规则和类型都与变量相同 2 虚参可以是变量名 数组名和过程名 但不允许用常量和数组元素 例 functionfat n x i 它表示了函数自变量的个数 顺序和类型 3 虚参是一个属于该函数子程序的局部变量 虚元的类型也可以用类说明语句在函数体中进行说明或按隐含约定方法确定 例 realfunctionintep x1 x2 x3 integerx1 x2 x3 2 子程序体用来完成具体任务的一个程序段 结构 说明语句可执行语句END语句 独立的程序单位 单独编译注意 若无虚参时 括号不能省 例 functionproc 函数子程序中所有变量和标号 除函数名和虚参外 与其它程序单位无任何联系 函数体的说明部分包括对虚参和本函数体内所用变量和数组的说明 例 functionrdh a x integera b cdimensionx 2 3 end 函数体中可设置一条或多条return语句 表示执行到此语句时返回调用程序 当然也可以不设return语句 例 functionfat n return end两种情况 当return语句和end语句紧挨着时 可省略return语句 需从中间返回时 return语句必不可少 函数名的作用函数名在函数体中 至少要有一次出现在赋值语句的左边 即 函数名 表达式 因为函数名要负责把函数值带回调用程序 例 求一个一维数组A n 的各数组元素之和 Functionsum A n Dimensiona 50 Sum 0 0Do10i 1 nsum sum a i 10Continuereturnend这里 sum是函数子程序的名字 它应作为一个变量名出现在程序体中 并且至少被赋值一次 这样 它才有值 在被调用后将值带回到主程序中 在主程序中可能有这样的语句 S1 sum x 50 S2 sum g 30 S s1 s2 例2 编一个求n 的子程序functionfac n fac 1 0do15i 1 nfac fac i15continueend 主程序中可以这样调用 fac 8 fac 11 fac 5 三 函数子程序的引用 函数子程序是不能直接执行的 只有在其他程序单位中对它引用时 才能控制转移到它的内部执行 函数子程序的引用和前面讲过的内部函数或语句函数引用形式完全一样 仅在表达式中出现 即只能出现在赋值语句的右边或WRITE语句中 三 函数子程序的引用 数组传递的首地址 实参与虚参在个数 类型 位置上必须一一对应 但名字可以不同 如 主程序子程序kh erg a m x functionerg x n q 三 函数子程序的引用 函数子程序的执行过程 函数子程序是一个外部过程 它不能直接单独控制执行 只有在其他程序单位中引用该函数名时才会控制转到函数子程序内部 大致分为四步 第一步 首先对实元是表达式的项求出表达式的值 然后将控制转移到函数子程序的FUNCTION语句 第二步 按排列顺序依次让对应的虚元和实元结合 程序单位之间的数据的传递 这个过程称为虚实结合 INTEGERSQL 6M SQ 10 L 4 5 WRITE 10 M10FORMAT 1X M 15 END 第三步 执行函数体中的各语句 第四步 当执行遇到END语句或RETURN语句时 函数子程序名带着赋给它的值返回到引用处继续执行程序 函数子程序的执行过程 INTEGERSQL 6M SQ 10 L 4 5 WRITE 10 M10FORMAT 1X M 15 END FUNCTIONSQ N K INTEGERSQSQ N KEND 四 函数子程序应用举例 例1 已知三角形三边a b c 求面积S 函数子程序FUNCTIONS X Y Z T X Y Z 2 0S SQRT T T X T Y T Z END 主程序WRITE 输入A B C READ A B CAREA S A B C WRITE 面积 AREAEND Sub 1 FUNCTIONFAC L FAC 1 0DOI 2 LFAC FAC IENDDOEND Sub 2 FUNCTIONCOM N M COM FAC N FAC M FAC N M END MAINPROGRAMDEMENSIONC 11 C 1 1 0DON 1 10DOM 1 NC M 1 COM N M ENDDOWRITE 10 C I I 1 N 1 ENDDO10FORMAT 1x 11F6 0 END 例5 编写一外部函数求一批数的最大值 函数子程序FUNCTIONBIG A N DIMENSIONA 20 BIG A 1 DOI 2 NIF A I GT BIG THENBIG A I ENDIFENDDOEND 主程序PARAMETER M 10 DIMENSIONX M WRITE 输入X 10 READ XY BIG X M WRITE YEND 思考 如何在外部函数中将最大值的的序号也求出 K K 1 K I K K 例6 求n 20 个数组元素之和及其平均值 函数子程序FUNCTIONSUM A N AVG DIMENSIONA 20 SUM 0 0DOI 1 NSUM SUM A I ENDDOAVG SUM NEND 函数子程序不仅可以由函数名带回函数值 还可以通过实参 形参的结合带回其它值 但不规范 主程序在引用了函数SUM后 可使用平均值AVG 例7 编写一个函数子程序课计算二维数组x 5 4 中任意行或任意列的元素之和 然后调用它来计算a 5 4 b 5 4 数组任一行或任一列元素之和 分析 任一行或任一列用变量L表示 设置一个逻辑变量GOG 来控制行或列 GOG true 第L行GOG false 第L列 Functionsum x l gog dimensionx 5 4 logicalgogsum 0 0if gog thendo20i 1 4sum sum x L i 20continueelsedo30i 1 5sum sum x i L 30continueendifend Mainprogramdimensiona 5 4 b 5 4 logicalk k1read k L a I j j 1 4 I 1 5 p sum a L k read k1 L1 b I j j 1 4 I 1 5 q sum b L1 k1 write k L pwrite k1 L1 qend 考虑 更通用的情况 任意矩阵 任意行 任意列 7 3子例程子程序 一 子例程子程序的概念二 子例程子程序的定义三 子例程子程序的调用四 子例程子程序应用举例 子例行子程序 子例行子程序也是Fortran的外部过程 它与函数子程序的主要差别在于 名字的作用不同 函数子程序名除了供调用外 还代表函数值 而子例行子程序名只供调用 要求返回值的方式不同 函数子程序是通过函数名将函数值带回调用程序 而子例行子程序是通过 虚实结合 将其新值转送回调用程序 调用方式不同 函数子程序的调用总是出现在表达式中 而子例行子程序必须用一条独立的语句调用 一 子例程的概念 函数子程序FUNCTIONSUM A N AVG DIMENSIONA 20 SUM 0 0DOI 1 NSUM SUM A I ENDDOAVG SUM NEND 当返回的值超过1个时 用函数子程序不规范 我们另辟蹊径 子例程SUBROUTINE S A N SUM AVG DIMENSIONA 20 SUM 0 0DOI 1 NSUM SUM A I ENDDOAVG SUM NEND 引例 前例6 求数组元素之和及平均值 一般形式 SUBROUTINES 虚参表 子例程子程序体 END 二 子例行子程序的定义 子例行语句 说明几点 子例行程序名的命名规则与变量名相同 但不标识类型 如果没有虚参 括号可以省略 例 subroutineabc 虚参可以是变量名 数组名和过程名 但不允许用常量和数组元素 它的说明部分包括对虚参和本子例行程序所用变量和数组的说明 子例行子程序的名字只起标识作用 没有值的概念 仅仅为了调用 因此 在子程序体中 它不允许出现 三 子例行子程序的调用一般形式 call子例行程序名 实参表 call子例行程序名执行过程 类似函数子程序 数组传递的首地址 与函数同 无参子例程 例 编写子例行程序分别求出5 5矩阵两个对角线上元素之和 programmainsubroutineopp a s1 s2 realw 5 5 reala 5 5 read w i j j 1 5 i 1 5 s1 0 0callopp w x1 x2 doi 1 5write 50 x1 x2s1 s1 a i i 50format 1x x1 f5 2 enddo 2x x2 f5 2 s2 0 0enddoi 1 5j 5 i 1运行结果 s2 s2 a i j x1 15 00 x2 25 00enddoend PROGRAMMAIN6REALW 5 5 CALLREADIN W CALLOPP W X1 X2 WRITE 100 X1 X210FORMAT 1x X1 F8 2 X2 F8 2 END SUBROUTINEREADIN A REALA 5 5 WRITE Enter5X5矩阵 DO10I 1 5READ A I J J 1 5 10CONTINUEEND 总结 函数子程序和子例行子程序的不同点 1 定义语句不同2 名字的作用不同3 调用方法不同4 用途不同 函数子程序带回一个值 子例行子程序可以带回一批值 数组 或者完成特定的操作 如 交换 排序等 7 4实参和虚参之间的数据传递 在Fortran程序设计中子程序的虚参可以是变量名 数组名 函数名 子例行程序和星号 下面讨论当虚参为变量名和数组名时的实参和虚参之间的数据传递问题 也称 虚实结合 问题 一 变量名作虚参时的虚实结合对应的实参可为同类型的常量 变量或数组元素 结合方式是按地址结合的 即虚参和实参共用一个存储单元 结合过程programmainintegera b c ddataa b 10 15 callsub a b c d print a b c dendsubroutinesub w x y z integerw x y zy w xz x yw xx yend 注意 当实参是数组元素时 虚实结合的过程和变量名相同 例 programmainsubroutinesub x a integera c 3 integerx adatac 1 2 3 a 2 xa 100 x 2 acallsub a c 2 endprint a a c 2 c 2 end 子程序 xa 主程序 ac 2 C C 1 二 数组名作虚参时的虚实结合 仅说明数值型数组 此时 对应的实参必须为同类型的数组名或数组元素 实参为数组名时的虚实结合是按地址结合的 即实参数组的第一个元素与对应虚参数组的第一个元素结合 实参数组的第二个元素与对应虚参数组的第二个元素结合 依此类推 几种情况 同维同体积 不同体积 例 programmainsubroutinectx b dimensiona 8 dimensionb 5 callctx a endend 若数组a b均为二维数组 如a 2 3 b 2 3 则 不同体积 如 b 2 2 不同维不同体积 若主程序中a 2 3 子程序中b 5 则 总结 数组的虚实结合与维数无关 结合原则 按照存储结构一一结合但注意 虚参数组的体积应小于实参数组的体积最好是同维同体积 不易出错 程序可读性强 实参为数组元素时的虚实结合仍按地址结合 但该数组元素与对应虚参数组的第一个元素结合 该数组元素的下一个元素与对应虚参数组的第二个元素结合 依此类推 例 programmainsubroutinectx y dimensionx 6 dimensiony 3 callctx x 3 endend 注 虚参数组的最后一个元素必须落在实参数组范围内 对上例而言 若定义y 6 则会出现 超界错 例 分别计算二维数组a 15 15 b 15 15 的主对角线元素之积P Q 再求P Q Functionacc x dimensionx 15 15 Acc x 1 1 do10i 2 15acc acc x i i 10continueend MainprogramDimensiona 15 15 b 15 15 Read a I J j 1 15 I 1 15 Read b I J j 1 15 I 1 15 P acc a Q acc b R p qPrint p p q q result rend 考虑 若只需求A数组主对角线的前三个元素之积呢 我们前面所用的数组 维界都是常数 其大小不可改变 要求解n阶线性方程组 对不同的n都要各编一套程序 这显然不合适 于是提出使用可调数组的想法 数组说明符中的维界用变量 上例中 将函数子程序或子例程中的A 20 改为A N 此数组即为可调数组 但是 A与N均需出现在形参中 可调数组的使用规则 1 可调数组只能在子程序中使用 2 可调数组与可调维中的变量均需列在形参中 PROGRAMMAINDIMENSIONA 10 B 4 3 M1 4M2 3CALLSUB A 10 B M1 M2 ENDSUBROUTINESUB X NX Y N1 N2 DIMENSIONX NX Y N1 N2 END 1 可调数组只能在子程序中使用 2 可调数组与可调维中的变量均需列在形参中 从数组的虚实结合规则可知 如果虚参数组的下标不可调 那么就会极大地影响子程序的通用性和灵活性 设计可调数组可以较好地解决这一问题 1 可调数组的概念
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 生育服务保障承诺书(5篇)
- 公交司机考试题库及答案
- 软件开发测试及维护合同书
- 滑县特岗地理考试真题及答案
- 枣庄物理中考试题及答案
- 汽车美容及维修服务合同书
- 合肥七中考试题型及答案
- 光电器件技术考试题库及答案
- 软件测试笔试题及答案解析大全
- 入伍政治考核笔试题及答案
- 小学道德与法治学科教师专业素质考试试题及答案
- GB∕T 23322-2018 纺织品 表面活性剂的测定 烷基酚和烷基酚聚氧乙烯醚
- 全国质量奖现场汇报材料(生产过程及结果)课件
- 政策评价-卫生政策分析课件
- 高中物理实验—测定物体的速度及加速度(含逐差法)
- 饮食习惯与健康
- 华为人力资源管理纲要2.0
- 第二章 园艺设施的类型、结构、性能及应用
- 银行卡收单外包服务协议范本
- 流动资金缺口测算表.xls
- 中国空白地图大全(可直接打印)(共49页)
评论
0/150
提交评论