fortran中save的用法?
编了一段程序,想看看save的用法,两个程序基本一致,只是a和b的赋值方法不用,第一个子程序a和b先声明再赋值,第二个子程序a和b声明时直接赋初值,但是结果却不一样,如下...
编了一段程序,想看看save的用法,两个程序基本一致,只是a和b的赋值方法不用,第一个子程序a和b先声明再赋值,第二个子程序a和b声明时直接赋初值,但是结果却不一样,如下,这是什么原因?
第一个程序:
program main
implicit none
call sub()
call sub()
call sub()
call sub()
end
subroutine sub()
implicit none
integer a,b
integer c
save a,b
a=1
b=2
c=a+b
a=c+1
b=c+2
write(*,*)a,b
end
运行结果:
4 5
4 5
4 5
4 5
第二个程序:
program main
implicit none
call sub()
call sub()
call sub()
call sub()
end
subroutine sub()
implicit none
integer::a=1
integer::b=2
integer c
save a,b
c=a+b
a=c+1
b=c+2
write(*,*)a,b
end
运行结果:
4 5
10 11
22 23
46 47
save的作用不就是保存子程序每次运行时变量的值,下次运行时直接调取吗? 展开
第一个程序:
program main
implicit none
call sub()
call sub()
call sub()
call sub()
end
subroutine sub()
implicit none
integer a,b
integer c
save a,b
a=1
b=2
c=a+b
a=c+1
b=c+2
write(*,*)a,b
end
运行结果:
4 5
4 5
4 5
4 5
第二个程序:
program main
implicit none
call sub()
call sub()
call sub()
call sub()
end
subroutine sub()
implicit none
integer::a=1
integer::b=2
integer c
save a,b
c=a+b
a=c+1
b=c+2
write(*,*)a,b
end
运行结果:
4 5
10 11
22 23
46 47
save的作用不就是保存子程序每次运行时变量的值,下次运行时直接调取吗? 展开
2个回答
推荐于2017-10-07 · 知道合伙人互联网行家
关注
展开全部
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语句同时使用才有意义。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询