Fortran函数调用之“变量”陷阱
最近笔者迫于应试压力强行修炼了一波“Fortran”编程,在编程过程中发现了一些让初学者猝不及防的陷阱,再此分享一下。
I fortran函数编程不同于C/C++、Java之处的几个要点:
在这里总结几个Fortran编程是需要注意的几个要点: 1、当调用含参函数时,必须给参数声明类型,这是必须的 2、当使用循环变量进行循环处理时,必须声明循环变量为integer类型 3、函数名代表函数的函数体内返回值,不论是在被调函数体内,还是在主调程序体内都必须声明以 函数名命名的返回值变量的(即声明函数的返回值类型),主调程序中用关键词 external修饰被调函数 声明的格式形如: real fun external fun
II 当调用fortran函数时,我们必须为函数的参数在参数体内声明类型后才能使用,不同于C/C++、Java在参数括号中直接声明,但有一个更显著的问题所在,在Fortran函数中声明并赋处置的变量在主调函数的连续调用中的值不会随着再次调用而重新初始化,看例:
! paractise.f90 ! ! FUNCTIONS: ! paractise - Entry point of console application. ! ! Example of displaying 'Hello World' at execution time. ! !**************************************************************************** ! ! PROGRAM: paractise ! ! PURPOSE: Entry point for 'Hello World' sample console application. ! !**************************************************************************** program paractise implicit none integer days, times, i real, allocatable ::averTemp(:) real fun external fun print *, "请输入天数:" read *, days print *, "请输入每天的时段数:" read *, times allocate(averTemp(days)) do i = 1, days averTemp(i) = fun(times) end do print*, "每天的各个时段的平均温度:" do i = 1, days print *, averTemp(i) end do stop end program paractise function fun(times) implicit none integer i, times !声明函数参数的类型,this is necessary real fun !声明函数的返回值类型, this is necessary too real, allocatable ::timesinfo(:) real ::sum = 0 !请关注这里!!!!! print *, "输出一下sum的值:", sum allocate(timesinfo(times)) print *, "请输入", times, "个时次的温度:" read *, timesinfo do i = 1, times sum = sum + timesinfo(i) end do fun = sum / times ! sum = 0 !这里需要注意的是,不同于C、Java类的语言, end function fun !循环体内对此调用同样的函数,函数体内定义 !的变量是在多次调用过程中是共用的,因此在本体累加的时候,每次需要将sum清
试运行截图:
按照Java类似的语言以往的编程逻辑,不应该这样的啊!!
于是,我尝试着将变量sum的声明与赋初值分开,即
real sum
sum = 0
有程序修改如下:
! paractise.f90 ! ! FUNCTIONS: ! paractise - Entry point of console application. ! ! Example of displaying 'Hello World' at execution time. ! !**************************************************************************** ! ! PROGRAM: paractise ! ! PURPOSE: Entry point for 'Hello World' sample console application. ! !**************************************************************************** program paractise implicit none integer days, times, i real, allocatable ::averTemp(:) real fun external fun print *, "请输入天数:" read *, days print *, "请输入每天的时段数:" read *, times allocate(averTemp(days)) do i = 1, days averTemp(i) = fun(times) end do print*, "每天的各个时段的平均温度:" do i = 1, days print *, averTemp(i) end do stop end program paractise function fun(times) implicit none integer i, times !声明函数参数的类型,this is necessary real fun !声明函数的返回值类型, this is necessary too real, allocatable ::timesinfo(:) real ::sum !请关注这里!!!!! sum = 0 !sum 类型声明与赋值分开 print *, "输出一下sum的值:", sum allocate(timesinfo(times)) print *, "请输入", times, "个时次的温度:" read *, timesinfo do i = 1, times sum = sum + timesinfo(i) end do fun = sum / times ! sum = 0 !这里需要注意的是,不同于C、Java类的语言, end function fun !循环体内对此调用同样的函数,函数体内定义 !的变量是在多次调用过程中是共用的,因此在本体累加的时候,每次需要将sum清零
试运行截图:
此时sum的值终于在再次调用函数是回归为0,是的处理逻辑正常。
III 显然,虽然在多次调用函数时,但函数体内的相同变量在内存中是同一块区域,必须在再入函数式将该变量进行初始化,方能正确处理逻辑,上面的处理方法,来讲函数体内的变量声明与赋初值分开既是实现这样的处理!
望每天进步一点,