Fortran Coder

查看: 4985|回复: 9
打印 上一主题 下一主题

[子程序] 调用子程序为什么每一次得出的结果都不一样呢

[复制链接]

50

帖子

18

主题

0

精华

熟手

F 币
276 元
贡献
167 点
跳转到指定楼层
楼主
发表于 2022-4-3 01:02:05 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
在下面的程序当中,我使用gfortran编译器进行编译,但是为什么每次我得到的结果都不一样呢?
[Fortran] 纯文本查看 复制代码
program para
        implicit none
        real(8)::f
        call func(1.0d0,1.0d0)
        print*,f
        end program
        subroutine func(x,y)
                implicit none
                real(8),intent(in) :: x, y
                real(8) :: f
                f = 2*x+3*y
        end subroutine
~                                                                                                                                                                                    
~                               

得出的结果如下:
另外为什么我这个地方用real,intent(out)::f就会报错呢

问题.png (114.21 KB, 下载次数: 184)

问题.png
分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

19

帖子

0

主题

0

精华

专家

F 币
370 元
贡献
122 点
沙发
发表于 2022-4-3 01:35:53 | 只看该作者
你在主程序里面声明了一个f,在子程序里面又声明了一个f,而且,在子程序里面的f没有输出。像这种情况你可以直接用function,或者subroutine但是加上输出intent(out)
[Fortran] 纯文本查看 复制代码
program main

    use iso_fortran_env, only: real64
    implicit none

    real(real64) :: f
    call func(1._real64, 1._real64, f)
    print *, f

contains

    subroutine func(x, y, ret)
        real(real64), intent(in) :: x, y
        real(real64), intent(out) :: ret

        ret = 2._real64*x + 3._real64*y
    end subroutine func

end program main

50

帖子

18

主题

0

精华

熟手

F 币
276 元
贡献
167 点
板凳
 楼主| 发表于 2022-4-3 13:47:08 | 只看该作者
唐汉 发表于 2022-4-3 01:35
你在主程序里面声明了一个f,在子程序里面又声明了一个f,而且,在子程序里面的f没有输出。像这种情况你可 ...

好的,那为什么我每次执行a.out的时候输出的结果都不一致呢

39

帖子

4

主题

0

精华

熟手

F 币
236 元
贡献
93 点
地板
发表于 2022-4-3 20:52:29 | 只看该作者
sqs 发表于 2022-4-3 13:47
好的,那为什么我每次执行a.out的时候输出的结果都不一致呢

子程序没有输出位。主程序中的 f等于没有赋值,每次运行 print的是个随机地址的初始值

39

帖子

4

主题

0

精华

熟手

F 币
236 元
贡献
93 点
5#
发表于 2022-4-3 21:02:11 | 只看该作者
本帖最后由 gps99 于 2022-4-3 21:03 编辑

增加输出位 是最直接的办法,上面的大咖已经给出代码。

另外,还有个老办法加common公共块。数据块内地址传递,和变量名无关。小程序可以用,数据多的话用module数据块代替
[Fortran] 纯文本查看 复制代码
program para
        implicit none
        real(8)::f
        common /d1/ f
        call func(1.0d0,1.0d0)
        print*,f
end program para

subroutine func(x,y)
        implicit none
        real(8),intent(in) :: x, y
        real(8) :: f
        common /d1/ f
        f = 2*x+3*y
end subroutine func


54

帖子

0

主题

0

精华

实习版主

F 币
653 元
贡献
214 点

元老勋章新人勋章

QQ
6#
发表于 2022-4-3 21:24:25 | 只看该作者
本帖最后由 布衣龙共 于 2022-4-3 21:29 编辑

楼主这个过程,是非常适合用函数的。
PS:任何程序,无论大小,都不推荐使用common,这东西就让它逝去吧。

[Fortran] 纯文本查看 复制代码
program para
  use , intrinsic :: iso_fortran_env, only: R8 => real64
  implicit none
  write(*,*) func(1.0_R8,1.0_R8)
contains
  Pure real(R8) Function func(x,y) result(f)
    real(R8),intent(in) :: x, y
    f = 2._R8*x+3._R8*y
  End Function func
end program para

50

帖子

18

主题

0

精华

熟手

F 币
276 元
贡献
167 点
7#
 楼主| 发表于 2022-4-4 15:55:21 | 只看该作者
布衣龙共 发表于 2022-4-3 21:24
楼主这个过程,是非常适合用函数的。
PS:任何程序,无论大小,都不推荐使用common,这东西就让它逝去吧。
...

啊哈,但是一旦我需要有三四个以上的输出结果,那这个时候就只能使用subroutine而不能使用function了呀,是这样吧

50

帖子

18

主题

0

精华

熟手

F 币
276 元
贡献
167 点
8#
 楼主| 发表于 2022-4-4 16:05:30 | 只看该作者
布衣龙共 发表于 2022-4-3 21:24
楼主这个过程,是非常适合用函数的。
PS:任何程序,无论大小,都不推荐使用common,这东西就让它逝去吧。
...

而且我不增加输出端,而是直接对主程序当中的变量进行赋值,这样可以么
[Fortran] 纯文本查看 复制代码
program main
    use iso_fortran_env, only: real64
    implicit none
    real(real64) :: f
    call func(1._real64, 1._real64)
    print *, f
contains
    subroutine func(x, y)
        real(real64), intent(in) :: x, y
        f = 2._real64*x + 3._real64*y
    end subroutine func
end program main

这两者又有什么区别呢

19

帖子

0

主题

0

精华

专家

F 币
370 元
贡献
122 点
9#
发表于 2022-4-5 02:04:25 | 只看该作者
sqs 发表于 2022-4-4 16:05
而且我不增加输出端,而是直接对主程序当中的变量进行赋值,这样可以么[mw_shl_code=fortran,true]progra ...

这样做是可以的,那是因为contains之后的所有子程序依然在一个“scope”里面。你在一个子程序里面也可以用contains来包含一个或多个子程序,他们也会分享上一层子程序的中的变量。但是我不太建议这么做。这样非常容易混淆。当你的程序越写越长了,我还是建议用module把这些都分开。

评分

参与人数 1F 币 +3 收起 理由
fcode + 3 说得对

查看全部评分

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

10#
发表于 2022-4-6 08:17:52 | 只看该作者
sqs 发表于 2022-4-4 16:05
而且我不增加输出端,而是直接对主程序当中的变量进行赋值,这样可以么[mw_shl_code=fortran,true]progra ...

如楼上所言,这样写的话,func函数就和主程序耦合在一起了。
当你需要把 func函数拷贝到其他地方使用时,就会有点“难受”。就不如单纯的解耦之后的函数那样,直接拷贝后直接调用。

对于小型的程序,当然怎么写差别都不大。对于大型程序,为了提高代码的复用性,推荐各程序单元间尽可能解耦。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-12-24 20:12

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表