fortran中save的用法?
答案:2 悬赏:10 手机版
解决时间 2021-02-19 06:18
- 提问者网友:轻浮
- 2021-02-18 19:33
fortran中save的用法?
最佳答案
- 五星知识达人网友:轻雾山林
- 2021-02-18 19:42
SAVE语句
函数子程序或子例行程序中用到的所有变量,在被调用前通常都没有确定的存储单元,每当子程序被调用时才临时分配存储单元,而且在退出子程序时这些存储单元又都被释放并重新分配另作它用。所以这些变量的值不被保留。在下次进入子程序时,给这些变量分配的可能是另外一些存储单元,上次调用时这些变量所具有的值已不复存在。我们称这些变量在子程序未调用时是无定义的。
在函数或子例行程序中可以使用SAVE说明语句来指定子程序中的某些变量的存储单元不被释放,它们的内容在退出子程序期间保持不变,在下次调用 时仍可使用。SAVE语句的形式如下:
SAVE 变量表 或: SAVE
“变量表”可以是本子程序中的变量名、数组名,若变量或数组名不止一个,它们之间用逗号隔开。注意,在SAVE语句中不允许出现虚拟参数名。当SAVE语句中带有“变量表”时,则为变量表中指定的变量和数组保留存储单元,如果SAVE语句中没有“变量表”,则表示让子程序中所有的变量和数组在程序执行期间都占有确定的存储单元,不因退出子程序而释放。
例:下面的程序中FUN是一个求阶乘的函数,每次调用此函数时,把最后一项乘数放在变量N0中,把阶乘的值放在变量F中。当下次调用此函数时,如果最后一项乘数大于等于上次最后一项,则不必再从头开始进行连乘运算,只需把上次的函数值再乘以N0+1、N0+2、…、N即可。
PROGRAM MAIN
WRITE(*,*)
WRITE(*,*) 'Enter N:'
READ(*,*) N
DO 10 WHILE(N.GE.0)
WRITE(*,'(1X,A,F7.1)')'FUN=',FUN(N)
WRITE(*,*)'Enter N:'
READ(*,*) N
10 CONTINUE
END
FUNCTION FUN(N)
SAVE N0,F
DATA N0/0/,F/1/
IF(N.LT.0)THEN
WRITE(*,*) 'Data error!!'
FUN=-1
RETURN
ELSE IF(N.LE.N0)THEN
F=1
N0=1
END IF
DO 10 I=N0+1,N
F=F*I
10 CONTINUE
FUN=F
N0=N
END
在子程序中,SAVE语句通常是和DATA语句同时使用的。如上例,当第一次调用FUN函数时,变量N0和F必须有初值,而在第二次及以后调用的时候,N0和F都保留着上次退出函数前的值,而且继续使用变量中的这些值,因而不必要再重新赋初值。对于这种只需在第一次调用时赋初值,后续调用不必赋初值的情况,使用DATA语句是合适的。当用DATA语句给子程序中的变量或数组赋初值时,这些变量和数组元素只是在子程序第一次调用时才有初值。如果没有SAVE语句说明,DATA语句中的变量和数组在第一次调用退出后就变成无定义的了。不要误解为调用一次子程序DATA语句就赋一次初值,因为DATA是非执行语句。如果每调用一次就需要赋一次相同的初值,这应该用赋值语句来实现。下面是一个求阶乘的函数FAC,当程序中多次调用该函数时,其结果是错误的;如果将DATA语句改为赋值语句,不管调用多少次,结果都正确。
FUNCTION FAC(N)
DATA F/1/
IF(N.LT.0)THEN
WRITE(*,*) 'Data error!!'
FAC=-1
RETURN
ELSE
DO 10 I=1,N
F=F*I
10 CONTINUE
END IF
FAC=F
END
注意:
(1)在子程序中不能用SAVE语句试图保存虚参的值,也不能用DATA语句给虚参赋初值,虚参的初值只能在子程序被调用时由实参传递。
(2)当用DATA语句给子程序中的变量或数组赋初值时,这些变量或数组元素只是在第一次调用该子程序时才有初值存在。在以后的调用时这些变量和数组元素都无确定的值(无定义的),不要误解为调用 一次子程序就赋一次初值,把DATA语句错当成执行语句(赋值语句)。
(3)子程序中同时使用SAVE和DATA语句时,SAVE语句应该放在DATA语句之前。通常,子程序中DATA语句和SAVE语句同时使用才有意义。
函数子程序或子例行程序中用到的所有变量,在被调用前通常都没有确定的存储单元,每当子程序被调用时才临时分配存储单元,而且在退出子程序时这些存储单元又都被释放并重新分配另作它用。所以这些变量的值不被保留。在下次进入子程序时,给这些变量分配的可能是另外一些存储单元,上次调用时这些变量所具有的值已不复存在。我们称这些变量在子程序未调用时是无定义的。
在函数或子例行程序中可以使用SAVE说明语句来指定子程序中的某些变量的存储单元不被释放,它们的内容在退出子程序期间保持不变,在下次调用 时仍可使用。SAVE语句的形式如下:
SAVE 变量表 或: SAVE
“变量表”可以是本子程序中的变量名、数组名,若变量或数组名不止一个,它们之间用逗号隔开。注意,在SAVE语句中不允许出现虚拟参数名。当SAVE语句中带有“变量表”时,则为变量表中指定的变量和数组保留存储单元,如果SAVE语句中没有“变量表”,则表示让子程序中所有的变量和数组在程序执行期间都占有确定的存储单元,不因退出子程序而释放。
例:下面的程序中FUN是一个求阶乘的函数,每次调用此函数时,把最后一项乘数放在变量N0中,把阶乘的值放在变量F中。当下次调用此函数时,如果最后一项乘数大于等于上次最后一项,则不必再从头开始进行连乘运算,只需把上次的函数值再乘以N0+1、N0+2、…、N即可。
PROGRAM MAIN
WRITE(*,*)
WRITE(*,*) 'Enter N:'
READ(*,*) N
DO 10 WHILE(N.GE.0)
WRITE(*,'(1X,A,F7.1)')'FUN=',FUN(N)
WRITE(*,*)'Enter N:'
READ(*,*) N
10 CONTINUE
END
FUNCTION FUN(N)
SAVE N0,F
DATA N0/0/,F/1/
IF(N.LT.0)THEN
WRITE(*,*) 'Data error!!'
FUN=-1
RETURN
ELSE IF(N.LE.N0)THEN
F=1
N0=1
END IF
DO 10 I=N0+1,N
F=F*I
10 CONTINUE
FUN=F
N0=N
END
在子程序中,SAVE语句通常是和DATA语句同时使用的。如上例,当第一次调用FUN函数时,变量N0和F必须有初值,而在第二次及以后调用的时候,N0和F都保留着上次退出函数前的值,而且继续使用变量中的这些值,因而不必要再重新赋初值。对于这种只需在第一次调用时赋初值,后续调用不必赋初值的情况,使用DATA语句是合适的。当用DATA语句给子程序中的变量或数组赋初值时,这些变量和数组元素只是在子程序第一次调用时才有初值。如果没有SAVE语句说明,DATA语句中的变量和数组在第一次调用退出后就变成无定义的了。不要误解为调用一次子程序DATA语句就赋一次初值,因为DATA是非执行语句。如果每调用一次就需要赋一次相同的初值,这应该用赋值语句来实现。下面是一个求阶乘的函数FAC,当程序中多次调用该函数时,其结果是错误的;如果将DATA语句改为赋值语句,不管调用多少次,结果都正确。
FUNCTION FAC(N)
DATA F/1/
IF(N.LT.0)THEN
WRITE(*,*) 'Data error!!'
FAC=-1
RETURN
ELSE
DO 10 I=1,N
F=F*I
10 CONTINUE
END IF
FAC=F
END
注意:
(1)在子程序中不能用SAVE语句试图保存虚参的值,也不能用DATA语句给虚参赋初值,虚参的初值只能在子程序被调用时由实参传递。
(2)当用DATA语句给子程序中的变量或数组赋初值时,这些变量或数组元素只是在第一次调用该子程序时才有初值存在。在以后的调用时这些变量和数组元素都无确定的值(无定义的),不要误解为调用 一次子程序就赋一次初值,把DATA语句错当成执行语句(赋值语句)。
(3)子程序中同时使用SAVE和DATA语句时,SAVE语句应该放在DATA语句之前。通常,子程序中DATA语句和SAVE语句同时使用才有意义。
全部回答
- 1楼网友:掌灯师
- 2021-02-18 21:02
是的,save属性的变量在下次调用函数时,依然保留上一次的值。
但是,第一段程序。你每次进入子程序,都手动让它重新变成了初值:a=1,b=2 。所以每次都一样。
第二段程序,虽然没有显式说明他们具有 save 属性。但在子程序中初始化的变量,则默认具有 save 属性。
integer :: a = 1
等同于:
integer , save :: a = 1
但不等于:
integer , save :: a
a = 1
但是,第一段程序。你每次进入子程序,都手动让它重新变成了初值:a=1,b=2 。所以每次都一样。
第二段程序,虽然没有显式说明他们具有 save 属性。但在子程序中初始化的变量,则默认具有 save 属性。
integer :: a = 1
等同于:
integer , save :: a = 1
但不等于:
integer , save :: a
a = 1
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯